【问题标题】:How to return all records and whether a related record exists?如何返回所有记录以及是否存在相关记录?
【发布时间】:2010-12-23 10:45:33
【问题描述】:

使用 Entity Framework 4 CTP5 我有一个基本模型和一个可以工作的基本 DbContext

public class Customer {
  public int CustomerId { get; set; }
  public int Name { get; set; }
  //...
  public ICollection<Address> Addresses { get; set; }
  public bool HasAddress {
    get {
      return Addresses.Count > 0;
    }
  }
}

public class Address {
  public int AddressId { get; set; }
  public string StreetLine1 { get; set; }
  //....
  public Customer Customer { get; set; }
}

如何查询我的 DbContext 以返回所有客户以及他们是否有地址?

一个客户可以有多个地址,当我只对他们是否有地址感兴趣时,我不想返回每个客户的所有地址。我用 context.Customers.Include(c =&gt; c.Addresses) 但返回每个客户的所有地址

【问题讨论】:

    标签: entity-framework linq-to-entities


    【解决方案1】:

    请记住,为了确定客户是否有地址,必须在服务器上执行聚合操作 (COUNT)。我认为您不能直接在 LINQ 谓词中使用 HasAddress 属性,因为 AFAIK 聚合操作不能在 LINQ-Entities 谓词中使用。

    所以你可能不得不这样做:

    var result = ctx.Customers.Select(x => new
                                      {
                                         Customer = x,
                                         HasAddress = x.Addresses.Count() > 0
                                      }).ToList();
    

    这将返回一组匿名类型,包括所有个客户,以及他们是否至少有一个地址。

    注意 Count 上的 () - 这执行实际的聚合操作 - 而 .Count 是客户端 LINQ 操作。

    编辑

    如果您想将该匿名类型放回 Customer 对象,您可以在查询实现之后执行此操作(例如,确保已在数据库上完成 .Count()): p>

    var result = ctx.Customers.Select(x => new
                                          {
                                             Customer = x,
                                             HasAddress = x.Addresses.Count() > 0
                                          }).ToList()
                                          .Select(x => new Customer
                                          {
                                             // left to right copy....
                                             HasAddress = true
                                          }).ToList();
    

    IMO 很脏,但它会起作用。

    【讨论】:

    • 谢谢,有没有办法将 x.Addresses.Count() > 0 投影到 Customer 对象的 HasAddress 属性中?我想保持我的模型干净,额外的匿名类型有点像视图模型
    • 你可以保持你的属性不变——使用.Count(没有()),但这将是对序列的客户端操作(例如在执行查询之后)。正如我提到的,您将无法在谓词中使用它。是的 - 如果合适的话,一定要投射到另一个类/类型中。
    • 我添加了一个编辑来展示如何将它放回客户对象中。但它相当肮脏。我不知道更好的方法。
    • 问题是您在困难的情况下想要查看客户是否有地址,但实际上并没有检索到它。也许你应该.Take(1)地址,这比上面的成本不高而且干净得多,并且可以节省你从左到右将属性从anon类型复制到Customer对象。
    猜你喜欢
    • 2015-12-10
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多