Linq查询活动子实体

时间:2011-12-16 14:18:42

标签: entity-framework silverlight-4.0 wcf-ria-services

我不知道在问题的标题中写什么。这是我的样本。我有一个Foo类,它有一个Bars集合,如下所示:

public class Foo  
{  
    public bool Active {get; set;}  
    public ICollection<Bar> Bars {get; set;}  
}  

public class Bar
{
    public bool Active {get; set;}
}

正如您所看到的,Foos和Bars都可以设置为非活动(Active = false)。我需要写一个服务(RIA),它将返回每个活动的Foo及其活动条 所以这就是我到目前为止所做的:

public IQueryable<Foo> GetFoos()
{
    return ObjectContext.Foos.Where(f => f.Active)
                             .Include("Bars");
}

问题在于上述查询会返回每个Foo的每个有效Bar,因此如何包含有效Bars

2 个答案:

答案 0 :(得分:1)

EF并没有让这一切变得简单,因为它违背了EF的设计理念。如果编写此查询很容易,以便每个Bars实体的Foo集合仅包含“有效”Bar实体,那么每个Foo实体都不会准确数据库状态模型。

另一方面,如果使用投影编写查询(而不是直接检索Foo实体),则可以获得更大的灵活性。例如,您可以这样编写查询:

var query =
    from f in ObjectContext.Foos
    where f.Active
    select new { Foo = f, ActiveBars = f.Bars.Where(b=>b.Active)}

此时你可以编写一个foreach循环,将活跃的Bar实体与每个Foo实体重新关联:

var results = query.ToList();

foreach (var r in results)
    r.Foo.Bars = r.ActiveBars;

最后在本地执行LINQ查询以返回结果:

return (from r in results select r.Foo).ToList();

我认为我刚刚概述的策略对于仅显示方案可以正常工作,但我会犹豫是否尝试更新以这种方式检索的实体。

答案 1 :(得分:1)

Include方法是LazyLoading的一部分。延迟加载是全部或全部,因此您不能告诉EF只加载一些条。

然而,你可以尝试做的是使用匿名对象:

context.Foos
.Where(f => f.Active)
.Select(f => new { Foo = f, Bars = f.Bars.Where(b => b.IsActive });