Linq Group by,连接并加载列表中的子实体

时间:2014-01-10 19:29:09

标签: linq entity-framework linq-to-entities ef-code-first

为了展示我想做的事情,我将简化一下我的模型。我完全知道如何使用SQL但我遇到了EF和LINQ的问题。

很抱歉这篇长篇文章。

我有下一个POCO:

public class Order
{
   public int Id {get; set;}
   public double Quantity {get; set;}   
   public List<Status> StatusChanges{get; set;}
}
public class Status
{
   public int Id {get; set;}
   public DateTime StatusDate {get; set;}
   public StatusType StatusType  {get; set;}
}
public class StatusType 
{
   public int Id {get; set;}
   public string Code {get; set;}
   public string Description {get; get;}
}

Order有多个Status,一个Status只有一个StatusType

我的问题:

1)如何在LINQ查询中选择包含所有已加载StatusType

的订单的列表

我尝试

var results= (from o in db.Orders
            select new {o.Id,o.Quantity,o.StatusChanges})
            .Include(o=>o.StatusChanges.Select(s=>s.StatusType));

但这不是我想要的,我想要一个包含OrderStatusStatusType的列表(即使Order信息是重复的)我知道我可以做一个双foreach但我想知道是否是一个单一的查询方式(或一个双查询一个数据库和另一个使用linq到实体)

2)如何使包含Order Id的列表和所有状态的代码连接起来。实施例

订单

Id    Quantity
1       2

状态

Id  StatusDate   StatusTypeId
1    01-10-2014       1
2    02-10-2014       2

StatusType

Id   Code  Description
1      E    Entered
2      C    Confirmed
3      D    Deleted

结果:

OrderId  Quantity    StatusResume
1         2           E,C

我知道我可以使用此question,但我不知道如何访问列表中已加载的元素。

2 个答案:

答案 0 :(得分:3)

来自 Ilija Dimov 的第一个答案应该有效。第二个更棘手,因为Aggregate扩展method is not supported by LINQ to Entities。这就是为什么你必须将必要的数据下载到内存并在内存中执行字符串连接作为LINQ to Objects查询。

var results = (from o in db.Orders
               select new
               {
                   o.Id,
                   o.Quantity,
                   o.StatusCodes.Select(c => c.StatusType.Code)
               }).AsEnumerable()
                 .Select(x => new {
                            x.Id,
                            x.Quantity, 
                            StatusResume = string.Join(',', x.StatusCodes)
                         }).ToList();
                   }).ToList();

答案 1 :(得分:2)

尝试以下查询:

1)如何在LINQ查询中选择包含所有已加载StatusType的订单的列表

var results = (from o in db.Orders
               from s in o.StatusChanges
               select new
                   {
                       OrderId = o.Id,
                       Quantity = o.Quantity,
                       StatusId = s.Id,
                       StatusDate = s.StatusDate,
                       StatusCode = s.StatusType != null ? s.StatusType.Code : null
                   }).ToList();

2)如何制作一个包含订单ID的列表和所有状态的代码连接

var results = (from o in db.Orders
                       select new
                           {
                               o.Id,
                               o.Quantity,
                               StatusCodes =
                           o.StatusChanges.Where(c => c.StatusType != null).Select(c => c.StatusType.Code)
                           }).ToList().Select(x => new
                               {
                                   x.Id,
                                   x.Quantity,
                                   StatusResume = string.Join(",", x.StatusCodes)
                               }).ToList();