convert sql query to linq with complex left join - linq

I am new to Linq joins.
i have a sql query as below. Please help me convert the same to linq.
select c.mem_id,
c.po_start,
c.po_end,
isnull(pp.new_policy_code,c.policy_no)
from claims_data c
left join tob_policy tp on (c.subgroup_id =tp.subgroup_id and c.category_id = tp.category_id
and c.service_from_date Between tp.Start_Date And isnull (tp.End_Date,
cast(GETDATE() as date)))
Left Join Tob_Policy_Period Pp On (Pp.Policy_Id = tp.Policy_Id And
c.service_from_date Between Pp.Start_Date And Pp.End_Date )
where c.cid = 13
and c.g_id = 19013
and c.mem_id = '123'
and c.code ='555'

Try with this code:
var results = (from c in yourmodelentity.claims_data
join tp in yourmodelentity.tob_policy on c.subgroup_id equals tp.subgroup_id && c.category_id equals tp.category_id && c.service_from_date Between tp.Start_Date && isnull (tp.End_Date, datetime.now)))
join Pp in yourmodelentity.Tob_Policy_Period on Pp.Policy_Id equals tp.Policy_Id && c.service_from_date Between Pp.Start_Date && Pp.End_Date
where c.cid = 13 && c.g_id = 19013 && c.mem_id = '123' && c.code ='555'
select new
{
c.mem_id,
c.po_start,
c.po_end
}).ToList();

Try with below code:
var results = (from c in modelentity.claims_data
join tp in modelentity.tob_policy on new { first = c.subgroup_id, second= c.category_id } equals new { first = tp.subgroup_id, second = tp.category_id } into tpjoin
from tplj in tpjoin.DefaultIfEmpty()
join pp in modelentity.Tob_Policy_Period on new { first = tplj.Policy_Id ?? 0 } equals new { first = Pp.Policy_Id } into ppjoin
from pplj in tpjoin.DefaultIfEmpty()
where ((c.service_from_date) >= tplj.Start_Date && (c.service_from_date) <= (tplj.End_Date ?? DateTime.Now)) &&
((c.service_from_date) >= pplj.Start_Date && (c.service_from_date) <= pplj.End_Date) &&
(c.cid = 13 && c.g_id = 19013 && c.mem_id = "123" && c.code = "555")
select new
{
c.mem_id,
c.po_start,
c.po_end,
policy_no = (pplj != null ? (pplj.new_policy_code ?? c.policy_no) : c.policy_no)
}).ToList();

Related

Linq Join table AND nullable variable

I'm trying to make a LINQ Query on Ef6 using a join on the db.ClincalAssets table where the AssetDisposalID Field is null
i.e. I don't want rows of data from that table where the AssetDisposalID is not null
The following code doesn't appear to work because it returns the same 23 results I had before I modified the code
var today = DateTime.Now.Date;
var tomorrow = today.AddDays(30);
var dateresult = db.ClinicalINSs.GroupBy(d => d.ClinicalAssetID)
.SelectMany(g => g.OrderByDescending(d => d.NextInspectionDate)
.Take(1));
var ClinicalIDVM = (from s in dateresult.Where(q => q.NextInspectionDate <= tomorrow)
join co in db.ClinicalAssets.Where (t => t.AssetDisposalID == null) on s.ClinicalAssetID equals co.ClinicalAssetID into AR
let subred = AR.OrderByDescending(subredASS => subredASS.ClinicalAssetID).FirstOrDefault()
join cp in db.ClinicalPATs on s.ClinicalAssetID equals cp.ClinicalAssetID into AP
let subpat = AP.OrderByDescending(SubPATASS => SubPATASS.ClinicalAssetID).FirstOrDefault()
orderby s.NextInspectionDate descending
select new ClinicalIDVM
{
ClinicalAssetID = s.ClinicalAssetID,
ProductName = subred.ProductName ,
SerialNo = subred.SerialNo == null ? "" : subred.SerialNo,
InspectionDate = subpat.InspectionDate,
NextInspectionDate = s.NextInspectionDate == null ? (DateTime?)null : s.NextInspectionDate,
}).ToList();
i have also tried this:
var today = DateTime.Now.Date;
var tomorrow = today.AddDays(30);
var dateresult = db.ClinicalINSs.GroupBy(d => d.ClinicalAssetID)
.SelectMany(g => g.OrderByDescending(d => d.NextInspectionDate)
.Take(1));
var ClinicalIDVM = (from s in dateresult from Disp in db.ClinicalAssets where s.NextInspectionDate <= tomorrow && Disp.AssetDisposalID == null
join co in db.ClinicalAssets on s.ClinicalAssetID equals co.ClinicalAssetID into AR
let subred = AR.OrderByDescending(subredASS => subredASS.ClinicalAssetID).FirstOrDefault()
join cp in db.ClinicalPATs on s.ClinicalAssetID equals cp.ClinicalAssetID into AP
let subpat = AP.OrderByDescending(SubPATASS => SubPATASS.ClinicalAssetID).FirstOrDefault()
orderby s.NextInspectionDate descending
select new ClinicalIDVM
{
ClinicalAssetID = s.ClinicalAssetID,
ProductName = subred.ProductName ,
SerialNo = subred.SerialNo == null ? "" : subred.SerialNo,
InspectionDate = subpat.InspectionDate,
NextInspectionDate = s.NextInspectionDate == null ? (DateTime?)null : s.NextInspectionDate,
}).ToList();
but I get al records duplicated.

C#: LINQ not returning the same result as SQL

I'm trying to convert the following SQL query to LINQ, but getting different result count with both,
SQL Query:
SELECT T5.CNTR, T5.BenefitCode,T5.ApprovedFlag,
T5.PaymentFrequencyCode, T5.InstalmentAmt, T5.TotalAmt,
T5.CarRego
FROM
dbo.EmployeeBenefit As T5
LEFT JOIN dbo.Payee ON T5.PayeeCntr = dbo.Payee.CNTR
LEFT JOIN dbo.BankDetails ON dbo.Payee.BankCntr = dbo.BankDetails.BankCntr
Left Join dbo.EmployeeCar As T4 on T5.EmployeeCarCntr=T4.Cntr
Inner Join dbo.EmployeeEntity As T1 On T5.EmployeeEntityCntr=T1.EmployeeEntityCntr
Inner Join dbo.EmployerEntity As T2 On T1.EmployerEntityCntr=T2.EmployerEntityCntr
where T5.EmployeeCntr = 117165
AND ((T5.EndDate is Null) OR (T5.EndDate >= GETDATE()))
LINQ:
var result = (from employeeBenefit in context.EmployeeBenefit
from payee in context.Payee.Where(x => x.Cntr == employeeBenefit.PayeeCntr).DefaultIfEmpty()
from bankDetails in context.BankDetails.Where(x => x.BankCntr == employeeBenefit.PayeeCntr).DefaultIfEmpty()
from employeeCar in context.EmployeeCar.Where(x => x.Cntr == payee.BankCntr).DefaultIfEmpty()
from employeeEntity in context.EmployeeEntity
where employeeEntity.EmployeeEntityCntr == employeeBenefit.EmployeeEntityCntr
from employeeEntity1 in context.EmployeeEntity
where employeeEntity.EmployerEntityCntr == employeeEntity1.EmployerEntityCntr
&& employeeBenefit.EmployeeCntr == iEmployeeID
&& (!employeeBenefit.EndDate.HasValue || employeeBenefit.EndDate >= DateTime.Now)
&& employeeBenefit.EmployeeCntr == 117165
&& employeeBenefit.CarRego == registration
select new
{
CNTR = employeeBenefit.Cntr,
BenefitCode = employeeBenefit.BenefitCode,
PaymentFrequencyCode = employeeBenefit.PaymentFrequencyCode,
InstalmentAmount = employeeBenefit.InstalmentAmt,
TotalAmount = employeeBenefit.TotalAmt,
CarRego = employeeBenefit.CarRego,
ApprovedFlag = employeeBenefit.ApprovedFlag
}).ToList();
Please let me know what i'm missing.
For the data in my database the SQL query is returning 10 records. But, the LINQ is returning 2700 records.
Not a full answer (I'm late for work) but:
var result = (from T5 in context.EmployeeBenefit
join PY in dbo.Payee on T5.PayeeCntr equals PY.CNTR into PY1
where T5.EmployeeCntr = 117165
select new {
CNTR = T5.Cntr,
...
}
).ToList();
It was the issue with the condition mismatch that i had done in the LINQ. The below query just worked fine. Thank you for helping me with the issue.
var result = (from employeeBenefit in context.EmployeeBenefit
from payee in context.Payee.Where(x => x.Cntr == employeeBenefit.PayeeCntr).DefaultIfEmpty()
from bankDetails in context.BankDetails.Where(x => x.BankCntr == payee.BankCntr).DefaultIfEmpty()
from employeeCar in context.EmployeeCar.Where(x => x.Cntr == employeeBenefit.EmployeeCarCntr).DefaultIfEmpty()
join employeeEntity in context.EmployeeEntity
on employeeBenefit.EmployeeEntityCntr equals employeeEntity.EmployeeEntityCntr
join employerEntity in context.EmployerEntity
on employeeEntity.EmployerEntityCntr equals employerEntity.EmployerEntityCntr
where employeeBenefit.EmployeeCntr == 117165 && (!employeeBenefit.EndDate.HasValue || employeeBenefit.EndDate >= DateTime.Now)
select new
{
CNTR = employeeBenefit.Cntr,
BenefitCode = employeeBenefit.BenefitCode,
PaymentFrequencyCode = employeeBenefit.PaymentFrequencyCode,
InstalmentAmount = employeeBenefit.InstalmentAmt,
TotalAmount = employeeBenefit.TotalAmt,
CarRego = employeeBenefit.CarRego,
ApprovedFlag = employeeBenefit.ApprovedFlag
}).ToList();

Ignore null and get full result

I have below linq select coding. The result become empty if db.actions.ACTC_DBID values are null. How to avoid that. I need to get the query result with null values.
var apList = (from r in db.components
join o in db.cmp_actionpanel on r.CMP_DBID equals o.CMP_DBID
join u in db.cmp_button on o.BTN_DBID equals u.BTN_DBID
join a in db.actions on o.ACTC_DBID equals a.ACTC_DBID
where (r.ORG_DBID == org && r.CMP_DBID == id)
orderby o.ORDER_IDX
select new
{
AP_DBID = o.AP_DBID,
CMP_NAME = r.CMP_NAME,
CMP_DBID = r.CMP_DBID,
BTN_NAME = u.BTN_NAME,
BTN_DBID = u.BTN_DBID,
ORDER_IDX = o.ORDER_IDX,
ALWAYS_VISIBLE = o.ALWAYS_VISIBLE,
ACTC_DBID = a.ACTC_DBID,
ACTION_CODE = a.ACTION_CODE,
ACTION_CMP_DBID = o.ACTION_CMP_DBID,
STARTS_JOB_PROGRESSION = o.STARTS_JOB_PROGRESSION,
VISIBLE_ON = o.VISIBLE_ON,
CAPTURE_INFO = o.CAPTURE_INFO,
COMMAND = o.COMMAND
}).ToList();
var apList = (from r in db.components
join o in db.cmp_actionpanel on r.CMP_DBID equals o.CMP_DBID
join u in db.cmp_button on o.BTN_DBID equals u.BTN_DBID
join a in db.actions on o.ACTC_DBID equals a.ACTC_DBID into aGroup
where (r.ORG_DBID == org && r.CMP_DBID == id)
orderby o.ORDER_IDX
from ag in aGroup.DefaultIfEmpty()
select new
{
AP_DBID = o.AP_DBID,
CMP_NAME = r.CMP_NAME,
CMP_DBID = r.CMP_DBID,
BTN_NAME = u.BTN_NAME,
BTN_DBID = u.BTN_DBID,
ORDER_IDX = o.ORDER_IDX,
ALWAYS_VISIBLE = o.ALWAYS_VISIBLE,
ACTC_DBID = ag.ACTC_DBID == null ? (int?)null : ag.ACTC_DBID,
ACTION_CODE = ag.ACTION_CODE,
ACTION_CMP_DBID = o.ACTION_CMP_DBID,
STARTS_JOB_PROGRESSION = o.STARTS_JOB_PROGRESSION,
VISIBLE_ON = o.VISIBLE_ON,
CAPTURE_INFO = o.CAPTURE_INFO,
COMMAND = o.COMMAND
}).ToList();

Query performance to compare date with many join and entity framework

I have this database model :
I use this query :
public List<Film> ListFilmsSortiesDes7DerniersJoursDVD()
{
DateTime dateDans7Jours = DateTime.Now.AddDays(7);
DateTime dateIlYa7Jours = DateTime.Now.AddDays(-7);
return Query(f => f.Releases.Where(r => r.Langue.langue_code == "FR" && r.TypeRelease.typerelease_code == "DVD").FirstOrDefault().release_date > dateIlYa7Jours
&& f.Releases.Where(r => r.Langue.langue_code == "FR" && r.TypeRelease.typerelease_code == "DVD").FirstOrDefault().release_date < dateDans7Jours && !string.IsNullOrEmpty(f.film_image)).ToList();
}
But the SQL generated have bad performance, about 1.3 seconds to return results (with SQL Server Express 2008 and I already have Index on correct fields):
SELECT [Extent1].[film_id] AS [film_id],
[Extent1].[film_image] AS [film_image],
[Extent1].[film_image_thumb] AS [film_image_thumb],
[Extent1].[film_format] AS [film_format],
[Extent1].[film_motsclefs] AS [film_motsclefs],
[Extent1].[film_nom] AS [film_nom],
[Extent1].[film_nomvf] AS [film_nomvf],
[Extent1].[film_synopsis] AS [film_synopsis],
[Extent1].[film_anneeproduction] AS [film_anneeproduction],
[Extent1].[film_budget] AS [film_budget],
[Extent1].[film_dateajout] AS [film_dateajout],
[Extent1].[film_actif] AS [film_actif],
[Extent1].[utilisateur_id] AS [utilisateur_id],
[Extent1].[film_francais] AS [film_francais],
[Extent1].[film_revenue] AS [film_revenue],
[Extent1].[filmgroupe_id] AS [filmgroupe_id]
FROM [dbo].[Film] AS [Extent1]
OUTER APPLY (SELECT TOP (1) [Filter1].[release_date] AS [release_date]
FROM (SELECT [Extent2].[film_id] AS [film_id],
[Extent3].[release_date] AS [release_date],
[Extent3].[typerelease_id] AS [typerelease_id]
FROM [dbo].[FilmRelease] AS [Extent2]
INNER JOIN [dbo].[Release] AS [Extent3]
ON [Extent3].[release_id] = [Extent2].[release_id]
INNER JOIN [dbo].[Langue] AS [Extent4]
ON [Extent3].[langue_id] = [Extent4].[langue_id]
WHERE N'FR' = [Extent4].[langue_code]) AS [Filter1]
INNER JOIN [dbo].[TypeRelease] AS [Extent5]
ON [Filter1].[typerelease_id] = [Extent5].[typerelease_id]
WHERE ([Extent1].[film_id] = [Filter1].[film_id])
AND (N'CINEMA' = [Extent5].[typerelease_code])) AS [Limit1]
CROSS APPLY (SELECT TOP (1) [Filter3].[release_date] AS [release_date]
FROM (SELECT [Extent6].[film_id] AS [film_id],
[Extent7].[release_date] AS [release_date],
[Extent7].[typerelease_id] AS [typerelease_id]
FROM [dbo].[FilmRelease] AS [Extent6]
INNER JOIN [dbo].[Release] AS [Extent7]
ON [Extent7].[release_id] = [Extent6].[release_id]
INNER JOIN [dbo].[Langue] AS [Extent8]
ON [Extent7].[langue_id] = [Extent8].[langue_id]
WHERE N'FR' = [Extent8].[langue_code]) AS [Filter3]
INNER JOIN [dbo].[TypeRelease] AS [Extent9]
ON [Filter3].[typerelease_id] = [Extent9].[typerelease_id]
WHERE ([Extent1].[film_id] = [Filter3].[film_id])
AND (N'CINEMA' = [Extent9].[typerelease_code])) AS [Limit2]
WHERE ([Limit1].[release_date] > '2013-02-04T00:07:48' /* #p__linq__0 */)
AND ([Limit2].[release_date] < '2013-02-18T00:07:48' /* #p__linq__1 */)
AND ([Extent1].[film_image] IS NOT NULL)
Do you please have any ideas to improve performance of this query ?
Ok why search complicated when the answer is simple :
public List<Film> ListFilmsSortiesDes7DerniersJoursCinema()
{
DateTime dateDans7Jours = DateTime.Now.AddDays(7);
DateTime dateIlYa7Jours = DateTime.Now.AddDays(-7);
return Query(f => f.Releases.Where(r => r.Langue.langue_code == "FR" && r.TypeRelease.typerelease_code == "CINEMA" && r.release_date > dateIlYa7Jours && r.release_date < dateDans7Jours).Any()).ToList();
}
I did a join in too

LINQ Join Errors

I'm getting the following error:
The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.
when using the code below
var ccrCodes = (from c in db.CCRCodes
join i in items on
new { c.baan_cat_fam_code, c.baan_cat_code } equals
new { i.baan_cat_family_code, i.baan_cat_code }
where i => i.contact_dt.Value.Year == date.Year && i.contact_dt.Value.Month == date.Month
select c).Distinct().OrderBy(c => c.code_desc);
What I'm trying to do in LINQ is create a multi-condition join and am running into problems. Any ideas?
Thanks,
Try giving names to the properties in your anonymous objects:
var ccrCodes = (from c in db.CCRCodes
join i in items on
new { FamCode = c.baan_cat_fam_code, CatCode = c.baan_cat_code } equals
new { FamCode = i.baan_cat_family_code, CatCode = i.baan_cat_code }
where i => i.contact_dt.Value.Year == date.Year && i.contact_dt.Value.Month == date.Month
select c).Distinct().OrderBy(c => c.code_desc);
EDIT: Alright, I have to confess, I am no expert on query syntax, but you want to filter the 'items' list before doing the join, like the following fluent version of your query:
db.CCRCodes
.Join(
items.Where(i => i.contact_dt.Value.Year == date.Year && i.contact_dt.Value.Month == date.Month),
x => new { FamCode = x.baan_cat_fam_code, CatCode = x.baan_cat_code },
x => new { FamCode = x.baan_cat_family_code, CatCode = x.baan_cat_code },
(o,i) => o
).Distinct().OrderBy(c => c.code_desc)
ANOTHER EDIT: Per Ahmad's suggestion:
var ccrCodes = (from c in db.CCRCodes
join i in items.Where(x => x.contact_dt.Value.Year == date.Year && x.contact_dt.Value.Month == date.Month) on
new { FamCode = c.baan_cat_fam_code, CatCode = c.baan_cat_code } equals
new { FamCode = i.baan_cat_family_code, CatCode = i.baan_cat_code }
select c).Distinct().OrderBy(c => c.code_desc);
YET ANOTHER EDIT: Per another Ahmad suggestion:
var ccrCodes = (from c in db.CCRCodes
from i in items
where i.contact_dt.Value.Year == date.Year && i.contact_dt.Value.Month == date.Month
&& c.baan_cat_fam_code == i.baan_cat_family_code && c.baan_cat_code == i.baan_cat_code
select c).Distinct().OrderBy(c => c.code_desc);

Resources