2012-11-21 33 views
0

我想給繼承類提供一個where子句給我的查詢的機會。這可能嗎?IQueryable where子句被繼承類重寫

protected IQueryable<EntityResult> GetEntities(ETBDataContext pContext) 
    { 
     return from e in pContext.Entities 
       where e.StatusCode == "Published" 

       //is there a way to add a dynamic where clause here? 
       //I would like to ask the inherited class for it's input: 

       && e.OtherColumn == "OtherValue" // <-- like GetWhere(e)? 

       //without having to select the column 

       orderby e.PublishDate descending 

       select new EntityResult 
       { 
        Name = e.Name, 
        Link = e.Link 
       }; 
    } 

先謝謝了!!!!!!!!!!

回答

0

您可以定義可以申請額外的虛擬方法,其中條件:

protected IQueryable<EntityResult> GetEntities(ETBDataContext pContext) 
{ 
    IQueryable<Entity> query = pContext.Entities 
     .Where(e => e.StatusCode == "Published"); 

    query = ApplyWhereClause(query); 

    return from e in query 
      orderby e.PublishDate descending 
      select new EntityResult 
       { 
        Name = e.Name, 
        Link = e.Link 
       }; 
    } 

protected virtual IQueryable<Entity> ApplyWhereClause(IQueryable<Entity> entities) 
{ 

} 

在你的派生類,你會那麼做:

protected override IQueryable<Entity> ApplyWhereClause(IQueryable<Entity> entities) 
{ 
    return entities.Where(/* insert your extra where clause here */); 
} 
+0

非常感謝。此代碼第一次編譯和工作。只有一個問題:所有這些仍然是在數據源上執行還是將其加載到內存中然後進行過濾? –

+0

有趣的是,我從來沒有想過在第一種方法中分裂它。 –

+0

只要您使用'IQueryable',就不會在數據庫中執行任何操作。只有在調用.ToList()或類似的函數時,或者在結果上開始執行foreach纔會實際執行鍼對數據庫的查詢。 – jeroenh

3

既然你返回一個IQueryable當使用資源的查詢纔會執行。所以只要它保持IQueryable,它將保留查詢。

有了這些知識,你可以簡單地套用在你的函數返回的IQueryable

像這樣的地方:

myObject.GetEntities(myContextObject).Where(x => x.id == 5); 

由於OtherCOlumn心不是有你所說的,你可以更改默認查詢:

protected IQueryable<EntityResult> GetEntities(ETBDataContext pContext) 
{ 
    return (from e in pContext.Entities 
      where e.StatusCode == "Published" 

      //is there a way to add a dynamic where clause here? 
      //I would like to ask the inherited class for it's input: 

      && e.OtherColumn == "OtherValue" // <-- like GetWhere(e)? 

      //without having to select the column 

      orderby e.PublishDate descending 

      select e).FirstOrDefault(); 
} 

然後在你的擴展位置做選擇。由於它保持查詢只要返回類型保持IQueryable這不會讓它變得更慢

+0

謝謝你,但得到的查詢不包括OtherColumn屬性可供選擇。所以當我在後面應用where子句時,就像.Where(er => er.OhterColumn)那樣,OtherColumn不存在。 –

+0

我編輯了我的答案 – middelpat

0

我不知道如何寫Linq表示法,因爲我總是喜歡使用Linq擴展方法,但它會看起來是這樣的:

protected IQueryable<EntityResult> GetEntities(ETBDataContext pContext) 
{ 
    var q = pContext.Entities 
     .Where(e => e.StatusCode == "Published"); 
    q = q.AddWhereCondition(q) 
     .OrderByDescending(e => e.PublishDate) 
     .Select(e => new EntityResult 
      { 
       Name = e.Name, 
       Link = e.Link 
      }); 
} 

protected virtual IQueryable<Entity> AddWhereCondition(IQueryable<Entity> query) 
{ 
    return query.Where(e => e.OtherColumn == "OtherValue"); 
} 

,或者通過提取其中()條件的LINQ表達式:

protected IQueryable<EntityResult> GetEntities(ETBDataContext pContext) 
{ 
    var q = pContext.Entities 
     .Where(e => e.StatusCode == "Published") 
     .Where(e => GetWhereCondition(e)) 
     .OrderByDescending(e => e.PublishDate) 
     .Select(e => new EntityResult 
      { 
       Name = e.Name, 
       Link = e.Link 
      }); 
} 

protected virtual Expression<Func<Entity, bool>> GetWhereCondition(Entity e) 
{ 
    return e => e.OtherColumn == "OtherValue"; 
}