2010-09-15 80 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關鍵字),否則集合將被忽略過濾器的延遲加載自動加載。