2010-09-15 92 views
10

我想加载一个实体和它的孩子有条件地(我只想在child.IsActive == true时加载孩子)。我如何执行以下操作?有条件的急切加载?

var parent = 
    from p in db.tblParents.Include("tblChildren") <-- where tblChildren.IsActive == true 
    where p.PrimaryKey == 1 
    select p; 

注意:我不想返回匿名类型。

谢谢。这样做

回答

9

一种方法是:

var parent = from p in db.tblParents where p.PrimaryKey == 1 
      select new { 
       Parent = p, 
       Children = p.tblChildren.Where(c => c.IsActive == true) 
      }.ToList(); 


然而,你可能不喜欢这个主意,返回一个匿名类型,那么我会建议以这样代码时:

var parent = (from p in db.tblParents where p.PrimaryKey == 1).Single(); 
var childrens = ctx.Contacts.Where(c => c.ParentID == 1 && c.IsActive == true); 
foreach (var child in childrens) { 
    parent.tblChildren.Add(child); 
} 
+0

我忽略提及我不想返回一个匿名类型......我需要返回一个类型为tblParent的对象(或集合)。 – 2010-09-15 14:18:18

+0

当然,我添加了另一个代码片段,它为您提供了一个强类型的父对象,其中包含所有符合条件的孩子。请看一看。 – 2010-09-15 14:25:02

+1

这是有道理的......但是,我们已经走出了渴望加载的境界。 – 2010-09-15 14:40:12

1

实体框架6引入拦截http://entityframework.codeplex.com/wikipage?title=Interception可用于调整SQL以筛选子项。

之前执行查询添加一个拦截和删除时,它不是有关:

var interceptor = new ActiveTagsInterceptor(); 
DbInterception.Add(interceptor); 

documents = context.Documents 
       .AsQueryable() 
       .Include(d => d.Tags) 

DbInterception.Remove(interceptor); 

样品拦截它增加了“[活动] = 1和”加载标签时:

public class ActiveTagsInterceptor : IDbCommandInterceptor 
{ 
    public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) 
    { 
    } 

    public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext) 
    { 
    } 

    public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) 
    { 
     // [Tag] AS [Extent6] ON => [Tag] AS [Extent6] ON [Extent6].[Active] = 1 And 
     const string pattern = "\\[Tag\\]\\sAS\\s\\[([\\w]+)\\]\\sON"; 
     const string replacement = "$& [$1].[Active] = 1 And "; 
     command.CommandText = Regex.Replace(command.CommandText, pattern, replacement); 
    } 

    public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) 
    { 
    } 

    public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) 
    { 
    } 

    public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext) 
    { 
    } 
} 
+0

尽管我不太喜欢手动修改Entity的SQL,但它完美地工作。有了这个,我不需要在实施软删除之后修改我的查询代码。 +1 – Nathan 2015-07-30 21:06:02

1

要能够应用过滤器,更好的选择是使用明确随着加载查询()而不是渴望 loading:

var parent = db.tblParents.Find(1); 
db.Entry(parent).Collection(p => p.tblChildren).Query(). 
    Where(child => child.IsActive).Load(); 

查询方式,可以访问加载相关实体的时候,实体框架将使用基础查询。您还需要关闭导航属性的延迟加载(删除Virtual关键字),否则集合将被忽略过滤器的延迟加载自动加载。