首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Linq To Entities查询

Linq To Entities查询
EN

Stack Overflow用户
提问于 2012-01-25 20:33:26
回答 2查看 164关注 0票数 4

考虑以下查询:

代码语言:javascript
复制
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();

在这个查询中,请看一下FollowUpDateServiceType,这两个都是我从Opportunity表中获取的,有没有其他方法可以同时获取它们。

表中的一对多关系类似于:ProspectProfile -> Opportunities

我所写的查询是否正确,或者是否有其他可以更容易地完成的工作。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-01-25 21:08:59

您唯一可以改进的是通过将代码更改为以下代码来避免两次排序:

代码语言:javascript
复制
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();

我对您的原始查询做了几处更改:

  1. 我将其更改为使用方法链语法。
  2. I删除了不必要的Skip(0).
  3. The,最大的变化是在Select部分:
    1. I将FirstOrDefault改为First,因为您无论如何都要访问返回值的属性。如果不存在商机,这将抛出描述性异常。这比您拥有的更好:在您的情况下,它将抛出一个NullReferenceException。这很糟糕,NullReferenceExceptions总是指示程序中的错误,并且根本没有描述性。
    2. 我把选择机会的部分移出了初始化器,所以我们只需要排序一次,而不是bug。

票数 4
EN

Stack Overflow用户

发布于 2012-01-26 04:33:19

您的查询中有相当多的问题:

  • 不能投影到实体(select new ProspectProfile)中。variable.
  • Using to Entities仅支持到匿名类型(select new)或不属于实体数据模型一部分的其他类型的投影LINQ to Entities (ServiceETA.ToString())
  • FirstOrDefault().ServiceETA (或FollowUpdate)将引发异常,因为EF无法在此类LINQ .ToList()中实现任何值在您的第一个查询之后,将在数据库中执行查询并加载完整的结果。稍后的Take会在内存中的完整列表中发生,而不是在数据库中。(您可以有效地将整个结果列表从数据库加载到内存中,然后丢弃除第一个Takeen.

对象之外的所有对象

要解决所有四个问题,您可以尝试以下操作:

代码语言:javascript
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9002791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档