我有一个非常简单的设置。表“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();
...
令人沮丧的是 LINQalways为此查询生成一个 LEFT OUTER JOIN,我尝试过的任何操作都没有什么区别。
从表面上看,这似乎有道理。 ObjectId 外键可为空,因此某些节点不会有关联的对象。但在我的查询中,我提供了一个对象 ID。我对没有关联对象的节点不感兴趣。
在这种情况下,INNER JOIN 是正确的做法,但如何说服 LINQ?
我认为你只需要让它成为左外连接。我想象当表达式树转换为 SQL 时,连接和相等谓词被视为结果查询的单独部分。换句话说,左外连接之所以存在,是因为您正在连接一个可为空的外键,并且相等部分是在之后写入的(可以这么说)。
它没有按照您想要的方式翻译真的很重要吗?当您使用 LINQ to SQL 时,您并不总能获得最有效的查询,这是一种可接受的权衡。大多数时候,如果你没有做任何疯狂的事情,并且如果你really认为这会影响性能什么的,你可以随时编写一个LINQ to SQL可以使用的存储过程。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)