LINQ to SQL multiple left join query with subquery at join condition - sql

I have a SQL query that takes a subquery as a parameter for a left join.
SELECT tblfLeaseDetail.Lease_Detail_ID,
tblfPayment.Payment_Date,
tblfAuthorization.Authorized,
tblvVendor.Vendor_Name,
tblvCounty.County
FROM tblfLeaseDetail
LEFT
JOIN tblfPayment
ON tblfPayment.Lease_Detail_ID = tblfLeaseDetail.Lease_Detail_ID
AND tblfPayment.Payment_ID =
( SELECT TOP 1
Payment_ID
FROM tblfPayment
WHERE tblfPayment.Lease_Detail_ID = tblfLeaseDetail.Lease_Detail_ID
ORDER BY Payment_Date DESC
)
LEFT
JOIN tblfAuthorization
ON tblfAuthorization.Lease_Detail_ID = tblfLeaseDetail.Lease_Detail_ID
AND tblfAuthorization.Authorization_ID =
( SELECT TOP 1
Authorization_ID
FROM tblfAuthorization
WHERE tblfAuthorization.Lease_Detail_ID = tblfLeaseDetail.Lease_Detail_ID
ORDER BY Authorized_Date DESC
)
LEFT JOIN tblvVendor
on tblvVendor.Vendor_ID = tblfLeaseDetail.Vendor_ID
LEFT JOIN tblvCounty
on tblvCounty.County_ID = tblfLeaseDetail.County_ID
I'm trying to convert it to LINQ. So far this is what I've done:
var leaseList = (from l in leases.tblfLeaseDetails
join a in leases.tblfAuthorizations on l.Lease_Detail_ID equals a.Lease_Detail_ID into la
from jla in
(from aj in leases.tblfAuthorizations
where aj.Lease_Detail_ID == l.Lease_Detail_ID
orderby aj.Authorized_Date descending
select aj.Authorization_ID).Take(1).DefaultIfEmpty()
join p in leases.tblfPayments on l.Lease_Detail_ID equals p.Lease_Detail_ID into lp
from jlp in
(from pj in leases.tblfPayments
where pj.Lease_Detail_ID == l.Lease_Detail_ID
orderby pj.Payment_Date descending
select pj.Payment_ID).Take(1).DefaultIfEmpty()
join v in leases.tblvVendors on l.Vendor_ID equals v.Vendor_ID into lv
from jlv in lv.DefaultIfEmpty()
join c in leases.tblvCounties on l.County_ID equals c.County_ID into lc
from jlc in lc.DefaultIfEmpty()
select new LeaseViewModel()
{
Lease_Detail_ID = l.Lease_Detail_ID,
Vendor_Name = jlv.Vendor_Name,
County = jlc.County,
Authorization = jla.Authorized,
Payment_Date = jlp.Payment_Date
}).Distinct()
This returns me an error at jla.Authorized and jlp.Payment_Date:
'int' does not contain a definition for 'Authorized' and no extension method 'Authorized' accepting a first argument of type 'int' could be found
The same error goes for Payment_Date.
Why are jla and jlp being considered ints? How can I make this query work?
EDIT:
This is the final and working LINQ query:
var leaseList = (from l in leases.tblfLeaseDetails
join a in leases.tblfAuthorizations on l.Lease_Detail_ID equals a.Lease_Detail_ID into la
from jla in la.DefaultIfEmpty()
where jla.Authorization_ID == (from aj in leases.tblfAuthorizations
where aj.Lease_Detail_ID == l.Lease_Detail_ID
orderby aj.Authorized_Date descending
select aj.Authorization_ID).Take(1).FirstOrDefault()
join p in leases.tblfPayments on l.Lease_Detail_ID equals p.Lease_Detail_ID into lp
from jlp in lp.DefaultIfEmpty()
where jlp.Payment_ID == (from pj in leases.tblfPayments
where pj.Lease_Detail_ID == l.Lease_Detail_ID
orderby pj.Payment_Date descending
select pj.Payment_ID).Take(1).FirstOrDefault()
join v in leases.tblvVendors on l.Vendor_ID equals v.Vendor_ID into lv
from jlv in lv.DefaultIfEmpty()
join c in leases.tblvCounties on l.County_ID equals c.County_ID into lc
from jlc in lc.DefaultIfEmpty()
select new LeaseViewModel()
{
Lease_Detail_ID = l.Lease_Detail_ID,
Lease_ID = l.Lease_ID,
XRef_Lease_ID = l.XRef_Lease_ID,
Vendor_Name = jlv.Vendor_Name,
Description = l.Description,
County = jlc.County,
Amount = l.Amount,
Payment_Due_Date = l.Payment_Due_Date,
Lease_Type = l.Lease_Type.ToString(),
Location_ID = l.Location_ID,
Active = l.Active,
Expiration_Date = l.Expiration_Date,
Authorization = jla.Authorized,
Payment_Date = jlp.Payment_Date
}).Distinct();

That is because you are selecting Authorization_ID and Payment_ID which are of type int into jla and jlp respectively . Try the below query and let me know how it worked for you.
var leaseList = (from l in leases.tblfLeaseDetails
join a in leases.tblfAuthorizations on l.Lease_Detail_ID equals a.Lease_Detail_ID into la
from jla in
(from aj in leases.tblfAuthorizations
where aj.Lease_Detail_ID == l.Lease_Detail_ID
orderby aj.Authorized_Date descending
select aj).Take(1).DefaultIfEmpty()
join p in leases.tblfPayments on l.Lease_Detail_ID equals p.Lease_Detail_ID into lp
from jlp in
(from pj in leases.tblfPayments
where pj.Lease_Detail_ID == l.Lease_Detail_ID
orderby pj.Payment_Date descending
select pj).Take(1).DefaultIfEmpty()
join v in leases.tblvVendors on l.Vendor_ID equals v.Vendor_ID into lv
from jlv in lv.DefaultIfEmpty()
join c in leases.tblvCounties on l.County_ID equals c.County_ID into lc
from jlc in lc.DefaultIfEmpty()
select new LeaseViewModel()
{
Lease_Detail_ID = l.Lease_Detail_ID,
Vendor_Name = jlv.Vendor_Name,
County = jlc.County,
Authorization = jla.Authorized,
Payment_Date = jlp.Payment_Date
}).Distinct()

Related

SQL to Linq - NET CORE 5

I have a SQL Statement like this:
select
b.ActivityRecordId, b.ActivityName, b.ActivityDetail,
b.CustomerId, e.CustomerName,
b.JobStatusId, c.JobStatusName, b.EstimateStartDate,
b.EstimateFinishDate, b.StartedDateTime, b.FinishedDateTime,
a.ActivityRecordProgressId, a.CustomerContactId,
Concat(d.FirstName, ' ', d.MiddleName, ' ', d.LastName) as fullName,
a.Started, a.Finished, a.ActivityDescription,
g.ActivityTypeId, g.ActivityTypeName, a.ActivitySubTypeId, f.ActivitySubTypeName
from
ActivityRecordProgress a
right join
ActivityRecord b on a.ActivityRecordId = b.ActivityRecordId
left join
ActivitySubType f on a.ActivitySubTypeId = f.ActivitySubTypeId
left join
ActivityType g on f.ActivityTypeId = g.ActivityTypeId
left join
CustomerContact d on a.CustomerContactId = d.CustomerContactId
inner join
JobStatus c on b.JobStatusId = c.JobStatusId
inner join
Customer e on b.CustomerId = e.CustomerId
Then I tried to convert it to Linq:
var obj = (from a in _db.ActivityRecords
join b in _db.ActivityRecordProgresses on a.ActivityRecordId equals b.ActivityRecordId into ab
from p in ab.DefaultIfEmpty()
join c in _db.Customers on a.CustomerId equals c.CustomerId
join e in _db.CustomerContacts on c.CustomerId equals e.CustomerId
join d in _db.JobStatuses on a.JobStatusId equals d.JobStatusId
join f in _db.ActivitySubTypes on p.ActivitySubTypeId equals f.ActivitySubTypeId
join g in _db.ActivityTypes on f.ActivitySubTypeId equals g.ActivityTypeId
select new OutstandingActivityViewModel {
ActivityRecordId = p.ActivityRecordId,
ActivityName = a.ActivityName,
ActivityDetail = a.ActivityDetail,
CustomerId = a.CustomerId,
CustomerName = c.CustomerName,
JobStatusId = a.JobStatusId,
JobStatusName = d.JobStatusName,
EstimateStartDate = a.EstimateStartDate,
StartedDateTime = a.StartedDateTime,
EstimateFinishDateTime = a.EstimateFinishDate,
FinishedDateTime = a.FinishedDateTime,
FirstName = e.FirstName, MiddleName = e.MiddleName, LastName = e.LastName,
Started = p.Started, Finished = p.Finished,
ActivityTypeName = g.ActivityTypeName, ActivitySubTypeName = f.ActivitySubTypeName,
ActivityDescription = p.ActivityDescription
}).ToListAsync();
But the result is not the same. The SQL result is the right one. It only 4 records. But in Linq, it appears 6 records. I'm sure I did something wrong with the linq syntax.
Can anyone show me where the mistake in my syntax is?
Really appreciated - thank you.
Thanks for commenting my question. It was very useful.
Finally I found the answer after trial and error using SQL generated. Below is the answer for the Linq syntax:
var obj = (from a in _db.ActivityRecords
join b in _db.ActivityRecordProgresses on a.ActivityRecordId equals b.ActivityRecordId into leftsatu
from leftkesatu in leftsatu.DefaultIfEmpty()
join c in _db.ActivitySubTypes on leftkesatu.ActivitySubTypeId equals c.ActivitySubTypeId into leftdua
from leftkedua in leftdua.DefaultIfEmpty()
join d in _db.ActivityTypes on leftkedua.ActivitySubTypeId equals d.ActivityTypeId into lefttiga
from leftketiga in lefttiga.DefaultIfEmpty()
join e in _db.CustomerContacts on leftkesatu.CustomerContactId equals e.CustomerContactId into leftempat
from leftkeempat in leftempat.DefaultIfEmpty()
join f in _db.JobStatuses on a.JobStatusId equals f.JobStatusId
join g in _db.Customers on a.CustomerId equals g.CustomerId
select new OutstandingActivityViewModel
{
ActivityRecordId = a.ActivityRecordId,
ActivityName = a.ActivityName,
ActivityDetail = a.ActivityDetail,
CustomerId = a.CustomerId,
CustomerName = g.CustomerName,
JobStatusId = a.JobStatusId,
JobStatusName = f.JobStatusName,
EstimateStartDate = a.EstimateStartDate,
StartedDateTime = a.StartedDateTime,
EstimateFinishDateTime = a.EstimateFinishDate,
FinishedDateTime = a.FinishedDateTime,
FirstName = leftkeempat.FirstName,
MiddleName = leftkeempat.MiddleName,
LastName = leftkeempat.LastName,
Started = leftkesatu.Started,
Finished = leftkesatu.Finished,
ActivityTypeName = leftketiga.ActivityTypeName,
ActivitySubTypeName = leftkedua.ActivitySubTypeName,
ActivityDescription = leftkesatu.ActivityDescription
}
);
It will generate SQL like:
SELECT [a].[ActivityRecordId], [a].[ActivityName], [a].[ActivityDetail], [a].[CustomerId], [c0].[CustomerName], [a].[JobStatusId], [j].[JobStatusName],
[a].[EstimateStartDate], [a].[StartedDateTime], [a].[EstimateFinishDate] AS [EstimateFinishDateTime], [a].[FinishedDateTime],
[c].[FirstName], [c].[MiddleName], [c].[LastName],
[a0].[Started], [a0].[Finished], [a2].[ActivityTypeName], [a1].[ActivitySubTypeName], [a0].[ActivityDescription]
FROM [ActivityRecord] AS [a]
LEFT JOIN [ActivityRecordProgress] AS [a0] ON [a].[ActivityRecordId] = [a0].[ActivityRecordId]
LEFT JOIN [ActivitySubType] AS [a1] ON [a0].[ActivitySubTypeId] = [a1].[ActivitySubTypeId]
LEFT JOIN [ActivityType] AS [a2] ON [a1].[ActivitySubTypeId] = [a2].[ActivityTypeId]
LEFT JOIN [CustomerContact] AS [c] ON [a0].[CustomerContactId] = [c].[CustomerContactId]
INNER JOIN [JobStatus] AS [j] ON [a].[JobStatusId] = [j].[JobStatusId]
INNER JOIN [Customer] AS [c0] ON [a].[CustomerId] = [c0].[CustomerId]

Convert SQL Query to LINQ query/Lambda expression

I am trying to fetch the results from the DB using the Entity Framework using the below SQL query:
SELECT
Header_Id,
Header_Number, Details_Id,
Details_Header_Date,
(SELECT TOP 1 c.[Comment_Description] FROM [Comment] c
WHERE c.[Comment_CarrierId] = i.[Header_CarrierId] AND c.[Comment_ParentEntityId] = i.[Header_Id]
ORDER BY c.Comment_AddedOn DESC) AS 'HeaderComments',
CONCAT(ht.[HeaderTracker_Reason], ' ', ht.[HeaderTracker_Notes]) AS 'RejectedComments',
at.[InternalComments] AS 'InternalComments',
CASE i.[Header_Status]
WHEN 'Pending' THEN ar.[HeaderTracker_ApprovedLvl] END AS 'ApprovedLevel',
CASE i.[Header_Status]
WHEN 'Pending' THEN ar.[HeaderTracker_DueBy] END AS 'ApprovedDueDate'
FROM [Header] i
LEFT OUTER JOIN [Details] ii
ON i.[Header_Id] = ii.[Details_HeaderId]
INNER JOIN [Carrier] t
ON t.[Carrier_Id] = i.[Header_CarrierId]
LEFT OUTER JOIN [HeaderTracker] ht
ON ht.[HeaderTracker_HeaderId] = i.[Header_Id] AND ht.[HeaderTracker_Type] = 'Rejected'
LEFT OUTER JOIN [AdjustmentTracker] at
ON at.[DetailsId] = ii.[Details_Id]
LEFT OUTER JOIN [HeaderTracker] ar
ON ar.[HeaderTracker_HeaderId] = i.[Header_Id]
AND i.[Header_Status] IN ('Paid', 'Pending', 'Approved', 'PaidWithAdj')
AND ar.[HeaderTracker_IsPending] = 1
The result output should be using LINQ query / LAMBDA expression
The following code is what I tried: (not sure how TOP 1 and CASE would come here + if & is also valid here)
var statuses = new string[] { "Paid", "Pending", "Approved", "PaidWithAdj" };
var hdrdet =
(
from hdr in dbContext.Headers
join det in dbContext.Details on hdr.Header_Id equals det.Header_Id into hdrdet
from h in hdrdet.DefaultIfEmpty()
join carr in dbContext.Carriers on hdr.Carrier_Id equals carr.Header_Carrier_Id into carrs
from c in carrs.DefaultIfEmpty()
join hdrtk in dbContext.HeaderTracker on hdr.Header_Id equals hdrtk.HeaderTracker_HeaderId && hdrtk.HeaderTracker_Type equals "Rejected" into hdrtks
from k in hdrtks.DefaultIfEmpty()
join adjt in dbContext.AdjustmentTracker on adjt.DetailsId equals det.Details_Id into adjts
from a in adjts.DefaultIfEmpty()
join pnd in dbContext.HeaderTracker on pnd.HeaderTracker_HeaderId equals hdr.Header_Id && hdr.Header_Status contains(statuses) && pnd.[HeaderTracker_IsPending] equals 1 into pnds
from p in pnds.DefaultIfEmpty()
select new
{
hdrid = Header_Id,
hdrnumber = Header_Number, Details_Id,
det_date = Details_Header_Date,
reason = HeaderTracker_Reason + ' ' + HeaderTracker_Notes,
intcomments = InternalComments
}
)

INSERT default values on the list of results of a query

I have to change a query, and want to add some pre-defined results (outputs) to the query when two values are found on two different columns.
Basically I want to add values to a new column on a query. I tried to use CASE but no luck until now.
SELECT DISTINCT
Q1.SCHD_ID,
Q1.SCHD_DESC,
Q1.TIMEZONE_ID,
Q1.DISPLAY_IN_SCHD_TZ,
Q1.LOGO_ID,
Q1.CODICE_SKOFF,
Q1.CODICE_MODULO,
case
when (Q1.PIANO_CODICE = 'FND001' AND Q1.CODICE_SKOFF = '2346') THEN 'testA'
WHEN (Q1.PIANO_CODICE = 'FND001' AND Q1.CODICE_SKOFF = '2347') THEN 'testB'
WHEN (Q1.PIANO_CODICE = 'FND001' AND Q1.CODICE_SKOFF = '3287') THEN 'testC'
WHEN (Q1.PIANO_CODICE = 'FND001' AND Q1.CODICE_SKOFF = '0000') THEN 'testD'
WHEN (Q1.PIANO_CODICE = 'TEST' AND Q1.CODICE_SKOFF = '4435') THEN 'testE'
ELSE 'NULL'
END as TITOLO_MODULO_SO
FROM
(SELECT
sc.SCHD_ID,
sc.SCHD_DESC,
sc.TIMEZONE_ID,
sc.DISPLAY_IN_SCHD_TZ,
SUBSTR(su1.USER_VALUE, 1 ,3) as LOGO_ID,
su1r.USER_DESC as PIANO_FINANZIAMENTO,
su1r.USER_ID as PIANO_CODICE,
cu1.USER_VALUE as TITOLO_MODULO,
cu2.USER_VALUE as CODICE_MODULO,
c.CPNT_TITLE as ARGOMENTO,
sr.START_DTE,
sr.END_DTE,
cu3.USER_VALUE as DURATA_CORSO,
su4.USER_VALUE as CODICE_SKOFF
FROM PA_SCHED sc
-- Campo "Piano principale di finanziamento"
left outer join PA_SCHED_USER su1 on sc.SCHD_ID = su1.SCHD_ID and su1.COL_NUM = 50
left outer join PA_USRRF_SCHED su1r on su1r.COL_NUM = su1.COL_NUM and su1.USER_VALUE = su1r.USER_ID
-- Informazioni ITEM
left outer join PA_CPNT c on c.CPNT_TYP_ID = sc.CPNT_TYP_ID and c.CPNT_ID = sc.ACT_CPNT_ID and c.REV_DTE = sc.REV_DTE
-- ITEM -> Titolo per finanziamenti
left outer join PA_CPNT_USER cu1 on cu1.CPNT_TYP_ID = c.CPNT_TYP_ID and cu1.CPNT_ID = c.CPNT_ID and cu1.REV_DTE = c.REV_DTE and cu1.COL_NUM = 10
-- ITEM -> Codice Finanziamento
left outer join PA_CPNT_USER cu2 on cu2.CPNT_TYP_ID = c.CPNT_TYP_ID and cu2.CPNT_ID = c.CPNT_ID and cu2.REV_DTE = c.REV_DTE and cu2.COL_NUM = 100
-- ITEM -> Ore finanziamento
left outer join PA_CPNT_USER cu3 on cu3.CPNT_TYP_ID = c.CPNT_TYP_ID and cu3.CPNT_ID = c.CPNT_ID and cu3.REV_DTE = c.REV_DTE and cu3.COL_NUM = 90
-- Dati della Scheduled Offering
left outer join PS_SCHD_RESOURCES sr on sr.SCHD_ID = sc.SCHD_ID
-- Facility
left outer join PA_FACILITY f on f.FACILITY_ID = sc.FACILITY_ID
-- Location
left outer join PA_LOCN l on l.LOCN_ID = sr.LOCN_ID
-- Campo "Banca capofila"
left outer join PA_SCHED_USER su3 on sc.SCHD_ID = su3.SCHD_ID and su3.COL_NUM = 10
left outer join PA_USRRF_SCHED su3ref on su3ref.COL_NUM = su3.COL_NUM and su3ref.USER_ID = su3.USER_VALUE
-- Campo "Multisocietario"
left outer join PA_SCHED_USER su2 on sc.SCHD_ID = su2.SCHD_ID and su2.COL_NUM = 30
-- Campo "Codice Finanz. SKOFF"
left outer join PA_SCHED_USER su4 on sc.SCHD_ID = su4.SCHD_ID and su4.COL_NUM = 99
) q1
Which is the best way to do it?
The dbms IS birt
I temp table on a query will work?
Thanks

How to convert this complex SQL Query with Subqueries into LINQ

How do I convert the following query into a Linq expression?
SELECT p.playerid,
(SELECT SUM(d.runs)
FROM deliveries d
INNER JOIN overs o ON d.overid = o.overid
WHERE o.isbatting = 1
AND o.gameid = 5
AND d.player_playerid = playerid) AS runsfor,
(SELECT SUM(d.runs)
FROM deliveries d
INNER JOIN overs o
ON d.overid = o.overid
WHERE o.isbatting = 0
AND o.gameid = 5
AND d.player_playerid = playerid) AS runsagainst,
( (SELECT SUM(d.runs)
FROM deliveries d
INNER JOIN overs o ON d.overid = o.overid
WHERE o.isbatting = 1
AND o.gameid = 5
AND d.player_playerid = playerid) -
(SELECT SUM(d.runs)
FROM deliveries d
INNER JOIN overs o ON d.overid = o.overid
WHERE o.isbatting = 0
AND o.gameid = 5
AND d.player_playerid =
playerid) ) AS runscontributed
FROM deliveries d
INNER JOIN players p ON d.player_playerid = p.playerid
INNER JOIN overs o ON d.overid = o.overid
WHERE o.gameid = 1
GROUP BY p.playerid
The results generated look like:
2 13 16 -3
4 -5 18 -23
5 -6 11 -17
7 4 1 3
8 5 7 -2
9 12 17 -5
10 -4 24 -28
12 19 1 18
Start out by simplifying.
SELECT d.*, o.*
FROM deliveries d
INNER JOIN overs o ON d.overid = o.overid
var joined = from d in deliveries
join o in overs on d.overid equals o.overid
select new { d, o };
Then simplify some more...
SELECT SUM(d.runs)
FROM deliveries d
INNER JOIN overs o ON d.overid = o.overid
WHERE o.isbatting = 1
AND o.gameid = 5
AND d.player_playerid = playerid
(from j in joined
where j.o.isBatting
&& j.o.gameId == 5
&& j.d.player.playerId == playerId
select j.d.runs).Sum();
Lather, rinse, repeat:
var joined = from d in deliveries
join players p on d.player_playerid equals p.playerid
join o in overs on d.overid equals o.overid;
where j.o.gameid = 1
select new { p, d, o };
var _runsfor = from j in joined
where j.o.isBatting
&& j.o.gameId == 5
&& j.d.player.playerId == some_player_id
select j;
var ungrouped = from j in joined
select new
{
playerId = j.p.playerid,
runsFor = _runsfor.Where(r => r.p.playerId == j.p.playerId)
.Sum(jn => jn.d.runs),
runsAgainst = //etc...
};
var grouped = from u in ungrouped
group new { u.runsFor, u.runsAgainst, /* etc... */ }
by u.playerId into player
select player;
I'm not certain this will do what you want, but it should give you a jumping off point.
Don't use this code directly; I wrote it freehand, and I'm not sure it will work the first time without some tweaking. The real point here is to simplify. Break your SQL query into smaller groups and write the LINQ for those. Then write some more LINQ to tie it all together. The ability to do that is one of the best things about LINQ.

Left Join Linq to Entity's Vb.net

I can't figure out that linq to entity query syntax. My problem is that if the value of the Calls table is null then noting comes up, I want to make something like a left join to get 'all' rows from the Calls table.
I tried to group it but I can't figure out the correct way to write it.
Dim TicketQuery As ObjectQuery = From c In EnData.Customer _
Join t In EnData.Calls On t.CustomerID Equals c.CustomerID _
Join Status In EnData.Lists On t.Status Equals Status.ListValue _
Join Project In EnData.Lists On t.Project Equals Project.ListValue _
Join Priorty In EnData.Lists On t.Priority Equals Priorty.ListValue _
Where c.Status > -1 And t.Status > -1 And Status.ListType = 1 And Project.ListType = 3 And Priorty.ListType = 2 _
Select New With {c.CustName, t.CallID, t.CallDate, t.CallTime, t.Description, Key .Status = Status.ListText, Key .Project = Project.ListText, t.DateModified, Key .Priority = Priorty.ListText}
How can I fix that?
Similar question: Linq to Sql: Multiple left outer joins
Microsoft Documentation: http://msdn.microsoft.com/en-us/library/bb918093.aspx#Y916
LINQ Examples from: http://msdn.microsoft.com/en-us/vbasic/bb737909
Left Outer Join
A so-called outer join can be expressed with a group join. A left outer joinis like a cross join, except that all the left hand side elements get included at least once, even if they don't match any right hand side elements. Note how Vegetables shows up in the output even though it has no matching products.
Public Sub Linq105()
Dim categories() = {"Beverages", "Condiments", "Vegetables", "Dairy Products", "Seafood"}
Dim productList = GetProductList()
Dim query = From c In categories _
Group Join p In productList On c Equals p.Category Into Group _
From p In Group.DefaultIfEmpty() _
Select Category = c, ProductName = If(p Is Nothing, "(No products)", p.ProductName)
For Each v In query
Console.WriteLine(v.ProductName + ": " + v.Category)
Next
End Sub
For left join in VB.net we can use Let
Dim q =
(From item In _userProfileRepository.Table
Let Country = (From p In _countryRepository.Table Where p.CountryId = item.CurrentLocationCountry Select p.Name).FirstOrDefault
Let State = (From p In _stateRepository.Table Where p.CountryId = item.CurrentLocationCountry Select p.Name).FirstOrDefault
Let City = (From p In _stateRepository.Table Where p.CountryId = item.CurrentLocationCountry Select p.Name).FirstOrDefault
Where item.UserId = item.ProfileId.ToString)
After the left join we can use group by
Dim q2 =
(From p In q Group p By p.Country, p.State, p.City Into Group
Select New With
{
.Country = Country,
.State = State,
.City = City,
.Count = Group.Count
}).ToList()