【发布时间】:2021-12-21 17:29:18
【问题描述】:
上下文
Itzik Ben-Gan 的T-SQL Fundamentals Third Edition一书在第 3 章中包含以下查询:
SELECT C.custid, C.companyname, O.orderid, O.orderdate
FROM Sales.Customers AS C
LEFT OUTER JOIN Sales.Orders AS O
ON O.custid = C.custid
AND O.orderdate = '20160212';
注意join子句有两个条件:
O.custid = C.custid
AND
O.orderdate = '20160212'
其他帖子中展示的技术
以下帖子(以及其他帖子)演示了如何通过JOIN 使用多个条件
LINQ to Entity : Multiple join conditions
LINQ Join with Multiple Conditions in On Clause
问题
根据上面分享的帖子,这是我想出的 EF Core 版本的查询:
var result =
from customer in db.Customers
join order in db.Orders
on
new
{
Key1 = customer.Custid,
Key2 = true
}
equals
new
{
Key1 = order.Custid,
Key2 = order.Orderdate == new DateTime(2016, 2, 12)
}
into Abc
from abc in Abc.DefaultIfEmpty()
select new
{
customer.Custid,
customer.Companyname,
Orderid = abc == null ? -1 : abc.Orderid,
Orderdate = abc == null ? new DateTime() : abc.Orderdate
};
但是,使用该代码时,join 上会出现一条红色波浪线,并显示以下消息:
CS1941:join 子句中的表达式之一的类型不正确。调用“GroupJoin”时类型推断失败。
docs.microsoft.com 上的编译器错误链接:
问题
我根据其他帖子中显示的示例对我的版本进行了建模。所以不确定我的例子中是什么导致了这个问题。
为给定的 SQL 调用设置 LINQ 查询的好方法是什么?
谢谢!
注意事项
如果您真的想自己运行查询,上述查询位于此处提供的项目中:
https://github.com/dharmatech/TSqlEf/blob/master/Chapter3e7/Program.cs
有关如何设置数据库,请参阅项目自述文件:
https://github.com/dharmatech/TSqlEf
克莱的建议
这是一种基于 Cly 的回答的方法,它使用 where 子句:
var result =
from customer in db.Customers
join order in db.Orders
on customer.Custid equals order.Custid
into Abc
from abc in Abc.DefaultIfEmpty()
where abc.Orderdate == new DateTime(2016, 2, 12)
select new
{
customer.Custid,
customer.Companyname,
Orderid = abc == null ? -1 : abc.Orderid,
Orderdate = abc == null ? new DateTime() : abc.Orderdate
};
如果我使用以下输出结果:
foreach (var item in result)
{
Console.WriteLine("{0} {1} {2}", item.Custid, item.Companyname, item.Orderid, item.Orderdate);
}
Console.WriteLine();
Console.WriteLine("{0} rows", result.Count());
我得到以下信息:
48 Customer DVFMB 10883
45 Customer QXPPT 10884
76 Customer SFOGW 10885
3 rows
如果我在 SSMS 中运行原始 SQL 代码,我会得到 91 行。
书中的练习描述还指出,预计需要 91 行。这是练习文本和预期输出:
这里是解决方案文本,它涉及连接背后的微妙之处以及为什么where 在这种情况下不适用:
【问题讨论】:
-
我会尝试从加入中删除
Key2部分并将order.Orderdate == new DateTime(2016, 2, 12)添加为where。它根本不是连接表达式,而是连接实体一侧的过滤器。 -
@cly,感谢您的建议!你会说应该在哪里插入
where子句?我试图将它放在各个地方的查询中,它们都会导致错误。 -
试试
from abc in Abc.Where(abc => abc.Orderdate == new DateTime(2016, 2, 12)).DefaultIfEmpty() -
@Charlieface,Omgosh ......这似乎完美无缺!我添加了一个答案来说明您建议的方法:stackoverflow.com/a/69892036/268581 非常有趣...谢谢!
-
@Charlieface,如果您决定根据您的建议添加自己的答案,我会投票赞成并删除我的。 :-)
标签: c# entity-framework linq tsql entity-framework-core