LINQ To Entities + Include +匿名类型问题

时间:2011-08-23 21:06:23

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

考虑:

班主任

班级项目

班级门票

课堂回复

客户有一个项目的子集合,项目有一个子集合的票证,而票证有一个子集合的回复。

var data = ctx.Set<Ticket>().Include(p => p.Client).
Select(p => new { Ticket = p, LastReplyDate = p.Replies.Max(q => q.DateCreated)});

不起作用。以这种方式选择数据时,既不加载项目也不加载客户端。

我知道如何让它发挥作用。我的问题是为什么它不能这样工作?

3 个答案:

答案 0 :(得分:12)

正如Ladislav所说,Include仅在您直接选择Ticket实体时才有效。由于您要预测其他信息,Include会被忽略。

这应该提供一个好的解决方法:

var data = ctx.Set<Ticket>()
    .Select(p => new 
         { 
             Ticket = p, 
             Clients = p.Client,
             LastReplyDate = p.Replies.Max(q => q.DateCreated)
         });

首先,每个Ticket的客户端都可以直接从匿名类型的Clients属性访问。此外,实体框架应该足够聪明,以确认您已为每个Client提取了整个Ticket集合,因此调用.Ticket.Client也应该有效。

答案 1 :(得分:5)

因为Include仅在您直接选择实体时才有效。完成投影后,Include将被忽略。我不会告诉你为什么,但它只是这样工作。

答案 2 :(得分:2)

另一种可能性是使用StriplingWarrior的解决方案,但随后从最终结果中清除中间数据:

var data = ctx.Set<Ticket>()
    .Select(p => new 
        { 
            Ticket = p, 
            Clients = p.Client,
            LastReplyDate = p.Replies.Max(q => q.DateCreated)
        })
    .AsEnumerable()
    .Select(p => new
        {
            Ticket = p.Ticket, 
            LastReplyDate = p.LastReplyDate
        });