I have a stored procedure that I'm converting to LINQ, but I'm a little stuck. Here's the SQL:
select
#name = tp.Name
, #Entity = tc.Entity
, #Name = tc.Name
, #ID = tpt.ID
, #Code = tptr.Code
from tbltprop tp
Left join tblcol tc on ( tc.id = tp.ID )
Left join tblPropday tpt on ( tpt.Id = tp.Id )
Left join tblProperResult tptr on (tptr.ID = tpt.Id )
where tp.id = #chsarpID1 //input ID i get in c#
and tpt.Id = #chsarpID2
I understand how to do a single join, but I'm having some trouble making a multiple join work. How would one go about this?
This might help you.......
var values= from tp in tbltprop
join tb in tblcol ON tp.id equals tb.id into gj
from gjd in gj.DefaultIfEmpty()
join tpt in tblPropday ON tp.id equals tpt.id into gk
from gkd in gk.DefaultIfEmpty()
join tptr in tblProperResult ON tp.id equals tptr.id into gl
from gld in gl.DefaultIfEmpty()
where tp.id == #charpID1 && gkd.Id == #CharpID2
select new
{
TpName = tp.Name,
Entity = gjd.Entity,
TPTName = gjd.Name,
ID = gkd.ID,
Code = gld.Code
};
Related
I have this linq
(from a in Customers
join b in CustomerContacts.Where(p => p.Contact.ContactType.Code == "phone") on a.Id equals b.CustomerId into bb
from b in bb.DefaultIfEmpty()
join e in CustomerContacts.Where(p => p.Contact.ContactType.Code == "email") on a.Id equals e.CustomerId into ee
from e in ee.DefaultIfEmpty()
join f in Bookings.Where(p => p.EntityId == 4) on a.Id equals f.CustomerId into ff
from f in ff.DefaultIfEmpty()
join h in CustomerAddresses on a.Id equals h.CustomerId into hh
from h in hh.DefaultIfEmpty()
where
(b.Contact.Value.Contains("123") || e.Contact.Value.Contains("123"))
&& (a.EntityId == 4 || f != null)
select new {
a.Id,
phone = b.Contact.Value,
email = e.Contact.Value,
count = Vehicles.Where(p => p.CustomerId == a.Id).Count(),
h.Address.State,
h.Address.Suburb
}
)
It translated to sql (mysql)
SELECT `a`.`Id`, `b.Contact`.`Value` AS `phone`, `e.Contact`.`Value` AS `email`, (
SELECT COUNT(*)
FROM `Vehicle` AS `p2`
WHERE `p2`.`CustomerId` = `a`.`Id`
) AS `count`, `h.Address`.`State`, `h.Address`.`Suburb`
FROM `Customer` AS `a`
LEFT JOIN (
SELECT `p`.*
FROM `CustomerContact` AS `p`
INNER JOIN `Contact` AS `p.Contact` ON `p`.`ContactId` = `p.Contact`.`Id`
INNER JOIN `ContactType` AS `p.Contact.ContactType` ON `p.Contact`.`ContactTypeId` = `p.Contact.ContactType`.`Id`
WHERE `p.Contact.ContactType`.`Code` = 'phone'
) AS `t` ON `a`.`Id` = `t`.`CustomerId`
LEFT JOIN `Contact` AS `b.Contact` ON `t`.`ContactId` = `b.Contact`.`Id`
LEFT JOIN (
SELECT `p0`.*
FROM `CustomerContact` AS `p0`
INNER JOIN `Contact` AS `p.Contact0` ON `p0`.`ContactId` = `p.Contact0`.`Id`
INNER JOIN `ContactType` AS `p.Contact.ContactType0` ON `p.Contact0`.`ContactTypeId` = `p.Contact.ContactType0`.`Id`
WHERE `p.Contact.ContactType0`.`Code` = 'email'
) AS `t0` ON `a`.`Id` = `t0`.`CustomerId`
LEFT JOIN `Contact` AS `e.Contact` ON `t0`.`ContactId` = `e.Contact`.`Id`
LEFT JOIN (
SELECT `p1`.*
FROM `Booking` AS `p1`
WHERE `p1`.`EntityId` = 4
) AS `t1` ON `a`.`Id` = `t1`.`CustomerId`
LEFT JOIN `CustomerAddress` AS `h` ON `a`.`Id` = `h`.`CustomerId`
LEFT JOIN `Address` AS `h.Address` ON `h`.`AddressId` = `h.Address`.`Id`
WHERE ((LOCATE('123', `b.Contact`.`Value`) > 0) OR (LOCATE('123', `e.Contact`.`Value`) > 0)) AND ((`a`.`EntityId` = 4) OR `t1`.`Id` IS NOT NULL)
and the result
however it contains duplicated Id, I want to add group by a.Id at the end to remove duplicated Id. Tried with group by but it cannot achieve some thing like this
SELECT `a`.`Id`, `b.Contact`.`Value` AS `phone`, `e.Contact`.`Value` AS `email`, (
SELECT COUNT(*)
FROM `Vehicle` AS `p2`
WHERE `p2`.`CustomerId` = `a`.`Id`
) AS `count`, `h.Address`.`State`, `h.Address`.`Suburb`
FROM `Customer` AS `a`
LEFT JOIN (
SELECT `p`.*
FROM `CustomerContact` AS `p`
INNER JOIN `Contact` AS `p.Contact` ON `p`.`ContactId` = `p.Contact`.`Id`
INNER JOIN `ContactType` AS `p.Contact.ContactType` ON `p.Contact`.`ContactTypeId` = `p.Contact.ContactType`.`Id`
WHERE `p.Contact.ContactType`.`Code` = 'phone'
) AS `t` ON `a`.`Id` = `t`.`CustomerId`
LEFT JOIN `Contact` AS `b.Contact` ON `t`.`ContactId` = `b.Contact`.`Id`
LEFT JOIN (
SELECT `p0`.*
FROM `CustomerContact` AS `p0`
INNER JOIN `Contact` AS `p.Contact0` ON `p0`.`ContactId` = `p.Contact0`.`Id`
INNER JOIN `ContactType` AS `p.Contact.ContactType0` ON `p.Contact0`.`ContactTypeId` = `p.Contact.ContactType0`.`Id`
WHERE `p.Contact.ContactType0`.`Code` = 'email'
) AS `t0` ON `a`.`Id` = `t0`.`CustomerId`
LEFT JOIN `Contact` AS `e.Contact` ON `t0`.`ContactId` = `e.Contact`.`Id`
LEFT JOIN (
SELECT `p1`.*
FROM `Booking` AS `p1`
WHERE `p1`.`EntityId` = 4
) AS `t1` ON `a`.`Id` = `t1`.`CustomerId`
LEFT JOIN `CustomerAddress` AS `h` ON `a`.`Id` = `h`.`CustomerId`
LEFT JOIN `Address` AS `h.Address` ON `h`.`AddressId` = `h.Address`.`Id`
WHERE ((LOCATE('123', `b.Contact`.`Value`) > 0) OR (LOCATE('123', `e.Contact`.`Value`) > 0)) AND ((`a`.`EntityId` = 4) OR `t1`.`Id` IS NOT NULL)
Group by `a`.`Id`
Have you tried something like this?
(from a in Customers
join b in CustomerContacts.Where(p => p.Contact.ContactType.Code == "phone") on a.Id equals b.CustomerId into bb
from b in bb.DefaultIfEmpty()
join e in CustomerContacts.Where(p => p.Contact.ContactType.Code == "email") on a.Id equals e.CustomerId into ee
from e in ee.DefaultIfEmpty()
join f in Bookings.Where(p => p.EntityId == 4) on a.Id equals f.CustomerId into ff
from f in ff.DefaultIfEmpty()
join h in CustomerAddresses on a.Id equals h.CustomerId into hh
from h in hh.DefaultIfEmpty()
where
(b.Contact.Value.Contains("123") || e.Contact.Value.Contains("123"))
&& (a.EntityId == 4 || f != null)
select new {
a.Id,
phone = b.Contact.Value,
email = e.Contact.Value,
count = Vehicles.Where(p => p.CustomerId == a.Id).Count(),
h.Address.State,
h.Address.Suburb
}).GroupBy(i => i.Id).ToList();
I'm trying to exclude the results of a first query from being included in the results of my second query.
The SQL equivalent is here, where A is my current query, and B is the old query.
I've been trying to use this guide to do the left join, but I can't seem to figure out how it should work in my case. I'm just not understanding how this should work (I can't get the syntax highlighting to be happy).
var emp = from employee in empl
join jc in jce on callout.job_class_code_fk equals jc.job_class_code_fk
join av in ab on employee.employee_id_pk equals av.employee_id_fk
join sh in sho on employee.employee_id_pk equals sh.employee_id_fk into lj
from rnd2 in lj.DefaultIfEmpty()
orderby employee.seniority descending
select new
{
eid = employee.employee_id_pk,
sen = employee.seniority,
nam = employee.employee_name,
pho = employee.phone_number,
lje = sho == null ? sho.employee_id_fk : null //left outer join with exclusion??
};
EDIT:: Based on the suggestions in the comments I've tried both of the following. While I don't have syntax issues any more, neither of the following return ANY results, so there's still something wrong here.
var emp = from employee in empl
join jc in jce on callout.job_class_code_fk equals jc.job_class_code_fk
join av in ab on employee.employee_id_pk equals av.employee_id_fk
join sh in sho on employee.employee_id_pk equals sh.employee_id_fk into lj
from rnd2 in lj.DefaultIfEmpty() where sho == null
orderby employee.seniority descending
select new
{
eid = employee.employee_id_pk,
sen = employee.seniority,
nam = employee.employee_name,
pho = employee.phone_number,
};
var emp = from employee in empl
join jc in jce on callout.job_class_code_fk equals jc.job_class_code_fk
join av in ab on employee.employee_id_pk equals av.employee_id_fk
join sh in sho on employee.employee_id_pk equals sh.employee_id_fk into lj
from rnd2 in lj.DefaultIfEmpty() where rnd2 == null
orderby employee.seniority descending
select new
{
eid = employee.employee_id_pk,
sen = employee.seniority,
nam = employee.employee_name,
pho = employee.phone_number,
};
Okay so (to me anyway) the answer that is the easiest to read and understand ended up being this.
Create two lists, the one I want to exclude, and the master list.
They we run master.Except(exclude) and voila. We've accomplished the effect of a left outer join with exclusion.
Here's the working code. The solutions above could very well have worked, as there was another problem with how the first list was being put together.
var ex = from employee in empl
join sh in sho on employee.employee_id_pk equals sh.employee_id_fk
select new
{
eid = employee.employee_id_pk,
sen = employee.seniority,
nam = employee.employee_name,
pho = employee.phone_number,
};
ex.Distinct();
//get a list of employees who have the enabled orientations and job classifications
var emp = from employee in empl
join jc in jce on employee.employee_id_pk equals jc.employee_id_fk
join av in ab on employee.employee_id_pk equals av.employee_id_fk
orderby employee.seniority descending
select new
{
eid = employee.employee_id_pk,
sen = employee.seniority,
nam = employee.employee_name,
pho = employee.phone_number,
};
emp = emp.Distinct();
emp = emp.Except(ex);
I have this query in SQL, and I want it to implement it in LINQ using Entity Framework, but how can I apply multiple tables left outer joins?
SELECT p.BookMastId as mastId
FROM BookMast p
left outer JOIN (SELECT y.BookMastId as Id, t.VrsnMastId as vrsn FROM BookReceiptMast t
left outer JOIN BookReceiptDtl y
on t.BookReceiptMastId = y.BookReceiptMastId) s
on p.BookMastId = s.Id where s.vrsn = 2
you can just use from var in collection join in syntax, something like this:
using(var cxt = new YourDataBaseContext()){
var firstJoin = from t in cxt.BookReceiptMast
join y in cxt.BookReceiptDtl
on t.BookReceiptMastId equals y.BookReceiptMastId
into yTemp
from y in yTemp.DefaultIfEmpty()
select new
{
Id = y != null ? y.BookMastId : 0,
vrsn = t.VrsnMastId
};
var allTables = from p in cxt.BookMast
join s in firstJoin
on p.BookMastId equals s.Id
into sTemp
from s in sTemp
where s.vrsn == 2
select new
{
mastId = p.BookMastId
};
}
I hope it helps you.
I have these queries in SQL and LINQ that were built to retrieve the same data. Unfortunately they are retrieving different amount of records (LINQ returns 1555 values, and SQL returns 1969) and I can't figure out why.
Please help me to find out what I'm missing. Follows the queries:
SQL:
SELECT l.Lease_Detail_ID, l.Lease_ID, l.XRef_Lease_ID, v.Vendor_Name, l.Description, c.County, l.Amount, l.Payment_Due_Date,
l.Lease_Type, l.Location_ID, l.Active, l.Expiration_Date, a.Authorized, p.Payment_Date
FROM tblfLeaseDetail AS l
LEFT JOIN tblvVendor AS v ON l.Vendor_ID = v.Vendor_ID
LEFT JOIN tblvCounty AS c ON l.County_ID = c.County_ID
LEFT JOIN tblfAuthorization AS a ON l.Lease_Detail_ID = a.Lease_Detail_ID
AND a.Authorization_ID = (SELECT TOP 1 Authorization_ID
FROM tblfAuthorization
WHERE Lease_Detail_ID = l.Lease_Detail_ID
ORDER BY Authorized_Date)
LEFT JOIN tblfPayment AS p ON l.Lease_Detail_ID = p.Lease_Detail_ID
AND p.Payment_ID = (SELECT TOP 1 Payment_ID
FROM tblfPayment
WHERE Lease_Detail_ID = l.Lease_Detail_ID
ORDER BY payment_date)
ORDER BY l.Lease_Detail_ID
LINQ: (Edited after a few comments)
var leaseList = (from l in leases.tblfLeaseDetails
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()
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 ascending
select aj.Authorization_ID).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 ascending
select pj.Payment_ID).FirstOrDefault()
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,
Authorized = jla.Authorized,
Payment_Date = jlp.Payment_Date
});
EDIT:
After analyzing the run-time SQL query generated by LINQ statement I found out that it's creating the Authorized sub-query in the wrong place. Here is what it looks like:
SELECT [t0].[Lease_Detail_ID], [t0].[Lease_ID], [t0].[XRef_Lease_ID], [t1].[Vendor_Name] AS [Vendor_Name], [t0].[Description], [t2].[County] AS [County], [t0].[Amount], [t0].[Payment_Due_Date], [t0].[Expiration_Date], [t3].[Authorized] AS [Authorized], CONVERT(NVarChar(1),[t0].[Lease_Type]) AS [Lease_Type], [t0].[Location_ID], CONVERT(Int,[t0].[Active]) AS [Active], [t4].[Payment_Date] AS [Payment_Date]
FROM [dbo].[tblfLeaseDetail] AS [t0]
LEFT OUTER JOIN [dbo].[tblvVendor] AS [t1] ON [t0].[Vendor_ID] = ([t1].[Vendor_ID])
LEFT OUTER JOIN [dbo].[tblvCounty] AS [t2] ON [t0].[County_ID] = ([t2].[County_ID])
LEFT OUTER JOIN [dbo].[tblfAuthorization] AS [t3] ON ([t0].[Lease_Detail_ID]) = [t3].[Lease_Detail_ID]
LEFT OUTER JOIN [dbo].[tblfPayment] AS [t4] ON ([t0].[Lease_Detail_ID]) = [t4].[Lease_Detail_ID]
WHERE ([t4].[Payment_ID] = ((SELECT TOP (1) [t5].[Payment_ID] FROM [dbo].[tblfPayment] AS [t5] WHERE [t5].[Lease_Detail_ID] = ([t0].[Lease_Detail_ID])
ORDER BY [t5].[Payment_Date] )))
AND ([t3].[Authorization_ID] = (( SELECT TOP (1) [t6].[Authorization_ID]
FROM [dbo].[tblfAuthorization] AS [t6]
WHERE [t6].[Lease_Detail_ID] = ([t0].[Lease_Detail_ID])
ORDER BY [t6].[Authorized_Date] )))
The problem is that it only made more confuse, once Payment and Authorized joins have exactly the same structure.
after some research I finally found how to do it. Here is the LINQ query that generates the SQL I was trying to get:
var leaseList = (from l in leases.tblfLeaseDetails
join p in leases.tblfPayments
on l.Lease_Detail_ID equals p.Lease_Detail_ID into lp
from jlp in lp.Where(x => x.Payment_ID == (from pj in leases.tblfPayments
where pj.Lease_Detail_ID == l.Lease_Detail_ID
orderby pj.Payment_Date ascending
select pj.Payment_ID).FirstOrDefault()).DefaultIfEmpty()
join a in leases.tblfAuthorizations on l.Lease_Detail_ID equals a.Lease_Detail_ID into la
from jla in la.Where(x => x.Authorization_ID == (from aj in leases.tblfAuthorizations
where aj.Lease_Detail_ID == l.Lease_Detail_ID
orderby aj.Authorized_Date ascending
select aj.Authorization_ID).FirstOrDefault()).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,
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,
Authorized = jla.Authorized,
Payment_Date = jlp.Payment_Date
});
How can I use left outer join in LINQ for the following SQL query?
SELECT a.EventID, a.PrizeId, b.PrizeName, b.PrizeValue, c.FightID, c.Winnerid, c.WinnerName
FROM tblUserprize a
JOIN tblPrizeDetails b
ON a.PrizeId=b.PrizeId
LEFT OUTER JOIN tblWinnersList c
ON a.EventID=c.EventID AND a.PrizeId=c.PrizeId AND c.FightID = 1534
WHERE a.EventID = 1320
It should look like this:
var userPrize = (
from a in tblUserprize
join b in tblPrizeDetails on a.PrizeId equals b.PrizeId
join c in tblWinnersList on new { a.EventID, a.PrizeId } equals new { c.EventID, c.PrizeId } into joinedTables
from item in joinedTables.DefaultIfEmpty()
where a.EventID == 1320 && item.FightID == 1534
select new
{
a.EventID,
a.PrizeId,
b.PrizeName,
b.PrizeValue,
item.FightID,
item.Winnerid,
item.WinnerName
});