我试图在linq查询中使用左外连接显式连接3个表,并且遇到了linq解析问题。执行内连接正确解析并返回数据,但使用左外连接失败。
示例:
var query = from p in DatabaseContext.Products
where p.ClientID == clientID
join l in DatabaseContext.Licenses on p.ProductID equals l.ProductID into pl
from pli in pl.DefaultIfEmpty()
join a in DatabaseContext.Articles on p.ArticleID equals a.ArticleID into pa
from pai in pa.DefaultIfEmpty()
select new SomeEntityDTO
{
SomethingFromP = p.Something,
SomethingFromL = pli.Something,
SomethingFromA = pai.Something
};
由于两个连接表都是第一个表的键,我可以通过删除另一个连接来单独测试每个表,例如,测试p到l的查询,然后p到a。这些测试查询功能完美。它也可以删除左外规则并获得适当的结果。
var query = from p in DatabaseContext.Products
where p.ClientID == clientID
join l in DatabaseContext.Licenses on p.ProductID equals l.ProductID
join a in DatabaseContext.Articles on p.ArticleID equals a.ArticleID
select new SomeEntityDTO
... the rest ...
在SQL事件探查器中查看有问题的查询(顶部代码示例)我看到前两个表已成功连接,例如:
SELECT p.Something, l.Something
FROM Products AS p
LEFT JOIN Licenses AS l ON p.ProductID = l.ProductID
WHERE p.ClientID = 5
ORDER BY p.ProductID
然后,在此成功查询之后,又是另外两个查询(彼此相同):
SELECT a.ArticleID, a.Something, <all fields, even when not specified in query>
FROM Articles AS a
ORDER BY a.ArticleID
外部连接的3个表将成功返回一个对象,只要我不尝试从&#34; a&#34;表。这样做时,我收到一个Null Exception错误,因为该表从未真正加入。
如上所述,删除外部联接规则会带回成功加入的查询。
我试图调整linq查询,确定Linq解析器有问题,但无济于事:
var query = from p in DatabaseContext.Products
from l in DatabaseContext.Licenses.Where(g => g.ProduktID == p.ProduktID).DefaultIfEmpty()
from a in DatabaseContext.Articles.Where(g => g.ArticleID == p.ArticleID).DefaultIfEmpty()
where ....
这解析为一组根本不起作用的CROSS APPLY,并且当复制到查询编辑器窗口时,配置文件查询根本不运行(与查看的3个单独查询相反)在第一个代码示例的分析器中)。我也尝试过更复杂的lambdas,这也是行不通的。
这是Linq解析器中的错误吗?我这样做完全错了吗? (根据显式左外连接的多个回答问题(与自然关联相反),我正确地做了。但是,它没有正确解析。我已经避免创建关联所以我可以在没有明确定义连接的情况下加入它们。这可能是必需的,如果没有它可以正常工作吗?
注意:每个表都有复杂的键,但我只需要根据单个键值加入(数据库是我无法改变的产品的一部分)。
使用。 DotNet Core,EntityFramework,EntityFrameworkCore.SqlServer等,版本均为1.0.1。
帮助?
答案 0 :(得分:1)
简短的回答是使用EF6而不是EFCore,如果您必须在您的entites上进行复杂的Linq查询,即使在1.1版本之后也是如此。与EF6相比,EFCore中仍然缺少太多东西。
路线图here。
就我而言,我保留了EFCore并使用了Context.Entity.FromSql(查询)方法来获得结果。这使我能够为大多数EF实体使用EFCore,从而保持对应用程序的前瞻性方法,同时允许针对不基于实际实体的复杂查询的特殊例外。计划是在EF Core成熟时替换那些FromSql查询。
在决定.FromSql之前,我还测试了View和存储过程的查询。在这两种情况下,我都失败了。对于存储过程,尚未实现命名参数,并且当前不支持视图,除非您试图欺骗EF认为视图实际上是一个表(它带来了自己的问题)。
要访问EF Core .FromSql,您需要安装以下软件包: Microsoft.EntityFrameworkCore.Relational