I am unsure of your circumstances but 'correct' solution would be to create Stored Procedure, and call that instead of composing this linq statement.
Here is an article how to do it
Question
I am bit new to Linq and entity framework and I have a requirement to write a linq query in my data access layer. The sql I want to produce is:
Select c.Configurationid,
ConfigurationDescription,
coalesce(d.enrolment,0) as Enrolment,
coalesce(d.accepts,0) as Accepts,
coalesce(d.rejects,0) as Rejects,
coalesce(d.incomplete,0) as Incomplete
from VVConfiguration c with (nolock)
LEFT JOIN (
Select ConfigurationId,
Sum(case when d.dialoguestatusid = 1 and d.processtypeid = 1 and e.CreateDate = dates.maxcreatedate then 1 else 0 end) as enrolment,
sum(case when ec.verificationdecisionid in (2, 3, 5) and d.ProcessTypeID = 2 and e.CreateDate = dates.maxcreatedate then 1 else 0 end) as accepts,
sum(case when ec.verificationdecisionid = 6 and d.ProcessTypeID = 2 and e.CreateDate = dates.maxcreatedate then 1 else 0 end) as rejects,
sum(case when d.dialoguestatusid = 4 and (e.CreateDate = dates.maxcreatedate or e.CreateDate IS NULL) then 1 else 0 end) as Incomplete
from dbo.dialogue d with (nolock)
LEFT JOIN exchange e with (nolock) on e.dialogueid = d.dialogueid
LEFT JOIN exchangeclaimant ec on e.exchangeid = ec.ExchangeID
left JOIN
(Select a.DialogueID,max(ex.CreateDate) as maxcreatedate from Dialogue a (nolock)
JOIN Exchange ex with (nolock) on a.dialogueId = ex.dialogueid
group by (a.dialogueid)) dates on dates.maxcreatedate = e.createdate and dates.DialogueID = d.DialogueID
group by d.configurationid ) d on d.configurationid = c.configurationid
Where c.OrganisationUnitId = '1234'
order by configurationdescription
By reading some articles and question on SO I came up with this query but the query is giving some wrong figures, and its taking too long to run.
Can someone please help me, what I am doing wrong?
(from c in this.context.VVConfiguration
join p in
(
from d in this.context.Dialogue
join e in this.context.Exchange on d.DialogueID equals e.DialogueID into ex
from exd in ex.DefaultIfEmpty()
join ec in this.context.ExchangeClaimant on exd.ExchangeID equals ec.ExchangeID into exc
from exec in exc.DefaultIfEmpty()
join date in
(
from di in this.context.Dialogue
join x in this.context.Exchange on di.DialogueID equals x.ExchangeID
join xc in this.context.ExchangeClaimant on x.ExchangeID equals xc.ExchangeID
group xc by new { di.DialogueID } into dates
select new
{
MaxDate = dates.Max(a => a.Exchange.CreateDate)
}
) on exec.Exchange.CreateDate equals date.MaxDate into xc
from xec in xc.DefaultIfEmpty()
group exec by new { d.ConfigurationID } into g
select new
{
ConfigurationID = g.Key.ConfigurationID,
Enrolment = g.Sum(a => ((a.Exchange.Dialogue.DialogueStatusID == 1 && a.Exchange.Dialogue.ProcessTypeID == 1) ? 1 : 0)),
Accepts = g.Sum(a => ((acceptsVerficationList.Contains(a.VerificationDecisionID) && a.Exchange.Dialogue.ProcessTypeID == 2) ? 1 : 0)),
Rejects = g.Sum(a => ((a.VerificationDecisionID == 6 && a.Exchange.Dialogue.ProcessTypeID == 2) ? 1 : 0)),
InComplete = g.Sum(a => (a.Exchange.Dialogue.DialogueStatusID == 4) ? 1 : 0)
}
) on c.ConfigurationID equals p.ConfigurationID into details
from configuration in details.DefaultIfEmpty()
where c.OrganisationUnitID == new Guid(organizationId)
orderby c.ConfigurationDescription
select new ConfigurationDetails
{
ConfigurationID = c.ConfigurationID,
ConfigurationDescription = c.ConfigurationDescription,
Enrolment = configuration.Enrolment,
Accepts = configuration.Accepts,
Rejects = configuration.Rejects,
InComplete = configuration.InComplete
}).ToList();
Solution
I am unsure of your circumstances but 'correct' solution would be to create Stored Procedure, and call that instead of composing this linq statement.
Here is an article how to do it