Linq to Entities的性能问题涉及很多专栏

时间:2011-08-31 15:58:47

标签: performance entity-framework linq-to-entities

我遇到了让linq让实体表现良好的问题。我有的查询(不是我的,维护某人的代码:-)),有几个包含我已经确定的所有必需的WPF屏幕都消耗了这个查询的结果。

现在,生成的SQL执行速度非常快,只返回一行数据。但是它返回570列,我认为性能损失是创建所有对象和所有这些字段的开销。

我尝试过使用延迟加载,但这似乎对性能没有任何影响。

我尝试删除任何不必要的“包含”语句,但看起来它们都是必需的。

这是linq查询:

var myQuery = 
                from appt in ctx.Appointments
                               .Include("ScheduleColumnProfile")
                               .Include("EncounterReason")
                               .Include("Visit")
                               .Include("Visit.Patient")
                               .Include("Visit.Patient.PatientInsurances")
                               .Include("Visit.Patient.PatientInsurances.InsuranceType")
                               .Include("Visit.Patient.PatientInsurances.InsuranceCarrier")
                               .Include("MasterLookup")
                               .Include("User1")
                               .Include("User2")
                               .Include("Site")
                               .Include("Visit.Patient_CoPay")
                               .Include("Visit.Patient_CoPay.User")
                               .Include("Visit.VisitInstructions.InstructionSheet")
                    where appt.VisitId == visitId 
                        && appt.MasterLookup.LookupDescription.ToUpper() != Rescheduled 
                        && appt.Site.PracticeID == practiceId
                        && appt.MasterLookup.LookupDescription.ToUpper() != Cancelled
                    orderby appt.AppointmentId descending
                    select appt;

SQL生成为4000行,选择语句中有570列,还有3或4个Union ALL,所以我不打算将其粘贴到此处,除非有人真的想看到它。基本上,我正在寻找一种方法来尽可能地摆脱工会,并将列减少到只需要的位置。

帮助!

: - )

2 个答案:

答案 0 :(得分:2)

如果有人跟踪,这就是最终为我工作的解决方案。感谢所有评论并提出建议的人......最终让我了解下面的内容。

            ctx.ContextOptions.LazyLoadingEnabled = true;

            var myQuery =
                from appt in ctx.Appointments
                where appt.VisitId == visitId
                    && appt.MasterLookup.LookupDescription.ToUpper() != Rescheduled
                    && appt.Site.PracticeID == practiceId
                    && appt.MasterLookup.LookupDescription.ToUpper() != Cancelled
                orderby appt.AppointmentId descending
                select appt;


            var myAppt = myQuery.FirstOrDefault();

            ctx.LoadProperty(myAppt, a => a.EncounterReason);
            ctx.LoadProperty(myAppt, a => a.ScheduleColumnProfile);
            ctx.LoadProperty(myAppt, a => a.Visit);
            ctx.LoadProperty(myAppt, a => a.MasterLookup);
            ctx.LoadProperty(myAppt, a => a.User1);
            ctx.LoadProperty(myAppt, a => a.User2);
            ctx.LoadProperty(myAppt, a => a.PatientReferredProvider);

            var myVisit = myAppt.Visit;

            ctx.LoadProperty(myVisit, v => v.Patient);
            ctx.LoadProperty(myVisit, v => v.Patient_CoPay);
            ctx.LoadProperty(myVisit, v => v.VisitInstructions);
            ctx.LoadProperty(myVisit, v => v.EligibilityChecks);

            var pat = myVisit.Patient;

            ctx.LoadProperty(pat, p => p.PatientInsurances);


            //load child insurances
            foreach (PatientInsurance patIns in myAppt.Visit.Patient.PatientInsurances)
            {
                ctx.LoadProperty(patIns, p => p.InsuranceType);
                ctx.LoadProperty(patIns, p => p.InsuranceCarrier);
            }

            //load child instruction sheets
            foreach (VisitInstruction vi in myAppt.Visit.VisitInstructions)
            {
                ctx.LoadProperty(vi, i => i.InstructionSheet);
            }

            //load child copays
            foreach (Patient_CoPay coPay in myAppt.Visit.Patient_CoPay)
            {
                ctx.LoadProperty(coPay, c => c.User);
            }

            //load child eligibility checks
            foreach (EligibilityCheck ec in myAppt.Visit.EligibilityChecks)
            {
                ctx.LoadProperty(ec, e => ec.MasterLookup);
                ctx.LoadProperty(ec, e => ec.EligibilityResponse);
            }

答案 1 :(得分:0)

我建议创建一个只包含您需要显示的属性的新类。当您投影到新类型时,您不需要包含Include语句,但您仍然可以访问该实体的导航属性。

var myQuery = from appt in ctx.Appointments
              where appt.VisitId == visitId 
                    && appt.MasterLookup.LookupDescription.ToUpper() != Rescheduled 
                    && appt.Site.PracticeID == practiceId
                    && appt.MasterLookup.LookupDescription.ToUpper() != Cancelled
              orderby appt.AppointmentId descending
              select new DisplayClass
              {
                 Property1 = appt.Prop1,
                 Proeprty2 = appt.Visit.Prop1,
                 .
                 .
                 .
              };