考虑以下查询:
var profilelst =
(
from i in dbContext.ProspectProfiles
where i.CreateId == currentUser
select new ProspectProfile
{
ProspectId = i.ProspectId,
Live = i.Live,
Name = i.Name,
ServiceETA = i.Opportunities.OrderByDescending(t => t.FollowUpDate)
.FirstOrDefault()
.ServiceETA.ToString(),
FollowUpDate = i.Opportunities.OrderByDescending(t => t.FollowUpDate)
.FirstOrDefault()
.FollowUpDate
}
)
.ToList();
return profilelst.OrderByDescending(c=>c.FollowUpDate)
.Skip(0).Take(endIndex)
.ToList();在这个查询中,请看一下FollowUpDate和ServiceType,这两个都是我从Opportunity表中获取的,有没有其他方法可以同时获取它们。
表中的一对多关系类似于:ProspectProfile -> Opportunities
我所写的查询是否正确,或者是否有其他可以更容易地完成的工作。
发布于 2012-01-25 21:08:59
您唯一可以改进的是通过将代码更改为以下代码来避免两次排序:
var profilelst
= dbContext.ProspectProfiles
.Where(i => i.CreateId == currentUser)
.Select(i =>
{
var opportunity
= i.Opportunities
.OrderByDescending(t => t.FollowUpDate)
.First();
return new ProspectProfile
{
ProspectId = i.ProspectId,
Live = i.Live,
Name = i.Name,
ServiceETA = opportunity.ServiceETA.ToString(),
FollowUpDate = opportunity.FollowUpDate
}
}).ToList();
return profilelst.OrderByDescending(c => c.FollowUpDate).Take(endIndex).ToList();我对您的原始查询做了几处更改:
Skip(0).Select部分:FirstOrDefault改为First,因为您无论如何都要访问返回值的属性。如果不存在商机,这将抛出描述性异常。这比您拥有的更好:在您的情况下,它将抛出一个NullReferenceException。这很糟糕,NullReferenceExceptions总是指示程序中的错误,并且根本没有描述性。
发布于 2012-01-26 04:33:19
您的查询中有相当多的问题:
select new ProspectProfile)中。variable.select new)或不属于实体数据模型一部分的其他类型的投影LINQ to Entities (ServiceETA.ToString())FirstOrDefault().ServiceETA (或FollowUpdate)将引发异常,因为EF无法在此类LINQ .ToList()中实现任何值在您的第一个查询之后,将在数据库中执行查询并加载完整的结果。稍后的Take会在内存中的完整列表中发生,而不是在数据库中。(您可以有效地将整个结果列表从数据库加载到内存中,然后丢弃除第一个Takeen.对象之外的所有对象
要解决所有四个问题,您可以尝试以下操作:
var profilelst = dbContext.ProspectProfiles
.Where(p => p.CreateId == currentUser)
.Select(p => new
{
ProspectId = p.ProspectId,
Live = p.Live,
Name = p.Name,
LastOpportunity = p.Opportunities
.OrderByDescending(o => o.FollowUpDate)
.Select(o => new
{
ServiceETA = o.ServiceETA,
FollowUpDate = o.FollowUpDate
})
.FirstOrDefault()
})
.OrderByDescending(x => x.LastOpportunity.FollowUpDate)
.Skip(startIndex) // can be removed if startIndex is 0
.Take(endIndex)
.ToList();这将为您提供一个匿名对象列表。如果您需要实体ProspectProfile列表中的结果,则必须在此查询后复制值。请注意,如果ProspectProfile没有LastOpportunity,则结果中的Opportunities可以为null。
https://stackoverflow.com/questions/9002791
复制相似问题