2008-10-20 44 views
3

我正在使用實體框架和Linq到實體。我創建了一個小型數據庫模式框架來實現版本化和本地化。現在每個實體都由兩個或三個表(即Product,ProductBase & ProductLocal)組成。自動添加一些Where子句到Linq表達式樹

我的LINQ總是包含以下樣板代碼:

from o in DB.Product 
from b in o.Base 
from l in o.Local 
WHERE o.VersionStatus == (int)VersionStatus.Active 
    && b.VersionStatus == (int)VersionStatus.Active 
    && l.VersionStatus == (int)VersionStatus.Active 
    && l.VersionLanguage == Context.CurrentLanguage 
select new ProductInstance { Instance = o, Base = b, Local = l } 

我想什麼做到的是把上述分爲:

(from o in DB.Product 
from b in o.Base 
from l in o.Local 
select new ProductInstance { Instance = o, Base = b, Local = l }).IsActive() 

或者在最壞的情況,是這樣的:

from o in DB.Product.Active() 
from b in o.Base.Active() 
from l in o.Local.Active() 
select new ProductInstance { Instance = o, Base = b, Local = l } 

我已經擴展了EDM生成的基類以實現一些enfo接口屬性(IVersionStatus和/或IVersionLanguage)。有什麼方法可以遍歷表達式樹,檢查表達式中的類型是否實現了該接口,然後相應地設置VersionStatus?

我非常喜歡它,就像第一個選項一樣簡單,只是少寫和/或忘記。我看過一些事例,在IEnumerable之後做了它,但我寧願不從數據庫中拉出超過我需要的數量。

感謝您的任何提示!

回答

0

我可能是錯的,但我不認爲DataLoadOptions作品與實體框架。

3

是的。

您可以通過在IQueryable上定義名爲IsActive的擴展方法來完成此操作。 IQueryable上有一個名爲「Expression」的屬性,它返回一個表達式樹,表示從您的查詢中生成的LINQ方法調用鏈。

在你的情況,這將是這個樣子:

DB.Product.SelectMany(o=>o.base, (o, b)=>new{o.b}).SelectMany(item=>o.local, (item, local)=>new {item.o, item.b, item.local}).Select(item=>new ProductInstance { Instance = item.o, Base = item.b, Local=item.Local}); 

的「DB.Product」是從第一個FROM子句的項目。每個剩餘的「SelectMany」調用是附加的從句。

然後,您可以挖掘表達式樹來收集所有from子句元素。看看它們的類型,然後最後爲where子句生成表達式樹。

然後,您的擴展方法將返回。使用where子句生成的IQueryable參數關閉。

當您嘗試對結果進行「foreach」時,生成的Where子句將隨後在服務器上與其餘查詢一起執行。

編輯:

請注意,如果你想這與明確的「加入」條款的工作,那麼你還需要除「的SelectMany」添加爲「加入」法的支持。