Context
The book T-SQL Fundamentals Third Edition by Itzik Ben-Gan contains the following query in chapter 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';
Note that the join clause has two conditions:
O.custid = C.custid
AND
O.orderdate = '20160212'
Techniques demonstrated in other posts
The following posts (among others) demonstrate how to use multiple conditions with a JOIN
LINQ to Entity : Multiple join conditions
LINQ Join with Multiple Conditions in On Clause
The issue
Based on the posts shared above, here's what I came up with for an EF Core version of the query:
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
};
However, with that code, a red squiggly comes up on join
with the following message:
CS1941: The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'GroupJoin'.
Link to the compiler error on learn.microsoft.com:
Question
I've modeled my version after the examples shown in the other posts. So not sure what in my example is causing the issue.
What's a good way to setup the LINQ query for the given SQL call?
Thanks!
Notes
The above query is in a project available here if you'd actually like to run the query yourself:
https://github.com/dharmatech/TSqlEf/blob/master/Chapter3e7/Program.cs
See the project readme for how to setup the database:
https://github.com/dharmatech/TSqlEf
Cly's suggestion
Here's an approach based on Cly's answer which uses a where
clause:
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
};
If I use the following to output the results:
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());
I get the following:
48 Customer DVFMB 10883
45 Customer QXPPT 10884
76 Customer SFOGW 10885
3 rows
Whereas if I run the original SQL code in SSMS, I get 91 rows.
The exercise description in the book also states that 91 rows are expected. Here's the exercise text and expected output:
Here's the solution text which goes into the subtleties behind the join and why where
isn't applicable in this case: