c# - 如何强制 LINQ to SQL 对可为空的外键执行 INNER JOIN?

标签 c# sql linq inner-join

我有一个非常简单的设置。表“Node”有一个可为空的外键“ObjectId”。这在我的数据库模型中表示为一对多关联。现在,我想运行一个查询,为我提供具有特定对象 ID 的所有节点对象。在直接 SQL 中,这非常简单:

SELECT Node.*, Object.*
FROM Node INNER JOIN Object
    ON Node.ObjectId = Object.ObjectId
WHERE Node.ObjectId = @objectId

但现在我想在 LINQ to SQL 中做同样的事情:

private static Func<MyDataContext, string, IQueryable<DataNode>> _queryGet =
        CompiledQuery.Compile(
            (MyDataContext context, string objectId) =>
                (from node in context.DataNodes
                 where node.ObjectId == objectId
                 select node));

var loadOptions = new DataLoadOptions();
loadOptions.LoadWith<DataNode>(node => node.DataObject);
context.LoadOptions = loadOptions;

DataNode node = _queryGet.Invoke(context, objectId).FirstOrDefault();
...

令人沮丧的是,LINQ 总是为此查询生成一个 LEFT OUTER JOIN,而我尝试过的任何事情都没有什么不同。

从表面上看,这似乎是有道理的。 ObjectId 外键可以为空,因此某些节点不会有关联的对象。但在我的查询中,我提供了一个对象 ID。我对没有关联对象的节点不感兴趣。

在这种情况下,INNER JOIN 是正确的做法,但我如何说服 LINQ?

最佳答案

我想你只需要让它成为一个左外连接。我想象当表达式树被转换为 SQL 时,连接和相等谓词被认为是结果查询的独立部分。换句话说,LEFT OUTER JOIN 之所以存在,是因为您要加入一个可为空的外键,并且等式部分写在后面(可以这么说)。

没有按照您的意愿进行翻译真的很重要吗?当您使用 LINQ to SQL 时,您并不总是获得可能的最高效查询这一事实是一种可接受的权衡。大多数时候,如果您没有做任何疯狂的事情,查询会非常有效,并且如果您真的认为它会影响性能或其他什么,您总是可以编写 LINQ to SQL 可以使用的存储过程.

关于c# - 如何强制 LINQ to SQL 对可为空的外键执行 INNER JOIN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3981813/

相关文章:

c# - 我在哪里可以找到 linq 的图形设计器

c# - 有没有办法将类型参数数组传递给泛型方法?

c# - 使用自定义字段进行 Elasticsearch 的 Serilog 配置

sql - 不小心将一个字符串插入到一个大的 int 列中。有没有机会恢复字符串?

c# - 从另一个表获取ID

c# - 为什么我不能在扩展 List 的类中调用 OrderBy?

c# - 为什么我的设计器属性没有在 ASPX 中序列化

c# - LINQ 查询中单个表的多个计数

sql - 在 oracle 数据库语句中使用 ENABLE 关键字的原因/用处是什么

linq - 如何使用linq过滤到一组的最大值