实体框架基于特定属性的预先加载

时间:2016-02-01 16:53:28

标签: c# entity-framework

我的应用程序中当前的EF设置是延迟加载,这在很大程度上是很好的。但是,我很遗憾尝试根据IsEnabled位属性加载相关实体列表。

在这个例子中,我只是返回一个实体列表。

return Context.Entities.ToList()

我们假设Entities对象包含ChildEntities列表,如下所示:

public class Entities
{        
    private string EntityName;

    private List<ChildEntities> ChildEntities;
}

public class ChildEntites
{        
    private string ChildEntityName;
    private bool IsEnabled;
}

我只想在加载ChildEntities列表时根据IsEnabled标记取出Entities

5 个答案:

答案 0 :(得分:2)

您可以使用Include()方法加载所有子实体,然后只选择那些启用的实体

Context.Entities.Include("ChildEntites").Select(c => e.IsEnabled == true)

另一种方法是获取过滤器实体,然后运行查询in this post

var data = from e in Context.Entities
            select new
            {
                Entities = e,
                Childs = e.ChildEntites.Where(c => c.IsEnabled == true) 
            };

var Results = data.ToArray().Select(x => x.Entities);

答案 1 :(得分:2)

我认为在您使用延迟加载或急切加载的情况下加载相关实体时无法过滤,除非您将查询投影到匿名类型或DTO,但是如果您有实体实例,您可以使用显式加载基于条件加载相关实体:

var entity=context.Entities.FirstOrDefault();
context.Entry(entity) 
        .Collection(b => b.ChildEntities) 
        .Query() 
        .Where(ce => ce.IsEnabled == true) 
        .Load(); 

如果因为你需要加载整个实体集合而不能满足你想要实现的目标,那么,正如我之前所说,你应该将查询投影到自定义类或匿名类型:

 var query= from e in Context.Entities.Include(c=>c.ChildEntities)
            select new EntityDTO
            {
                EntityName= e.EntityName,
                ChildEntites= e.ChildEntites.Where(c => c.IsEnabled == true) 
            };

答案 2 :(得分:1)

我会推荐这种方法。我要么延迟加载IsEnabled = false,要么在单独的调用中加载,其中IsEnabled = true或者一旦你有一个延迟加载的集合,在一个单独的调用中,得到IsEnabled = true的子项。我不相信你能在一次通话中做到这一点。另一种选择是存储过程。我希望这会有所帮助。

答案 3 :(得分:1)

使用投影

var entities = context.Entities
                      .Select(x => new {x, x.ChildEntities.Where(y => y.IsEnabled))
                      .ToList() // resolve from database before selecting the main entity
                      .Select(x => x.x);

使用第三方库

EF + Query IncludeFilter可让您轻松过滤相关实体

var entities = context.Entities.IncludeFilter(x => x.ChildEntities.Where(y => y.IsEnabled))
                               .ToList();

您可以找到文档here

免责声明:我是项目所有者EF+

答案 4 :(得分:1)

我有类似的问题。我用以下方式解决了这个问题。

在模型实体中创建一个新方法。让我们称之为ChildEntitiesEnabled

 public ICollection<ChildEntity> ChildEntitiesEnabled()
 {
      //First I get the full list using the lazy loading...
      var allChildEntities=ChildEntities.ToList();

      //do further processing if there is data
      if(allChildEntities!=null && allChildEntities.Count()>0)
      {

         var childEntitiesEnabled =  ChildEntities.Where(x=>x.Enabled==true).ToList();

         return childEntitiesEnabled;
      }

      return null; //or you can return an empty list...
 }

我喜欢这种方法,因为您可以在模型可用的任何地方使用它,而不会在任何地方散布复杂的代码。此外,您不会丢失所有ChildEntities数据......也可以从原始呼叫中获得。