2013-07-05 35 views
2

我正在使用實體框架來訪問我的域模型,所有這些模型都實現了一個指定屬性的接口(IPublishable),以指示項目是否已發佈。.NET LINQ to Entities基類where子句的泛型類型

當從前端訪問項目時,我總是希望過濾掉未發佈的項目。所以,每次我寫一個查詢我在做一些與此類似(其中以下DbSets Objects1和Objects2都實現時間IPublishable

context.Objects1.Where(x => x.IsPublished ...).OrderBy(x => x.Id).ToList() 
context.Objects2.Where(x => x.IsPublished ...).First() 

什麼是理想的是,如果我能注入共同Where()條款爲我所有的我的web應用程序中查詢,或者出現編寫擴展方法,我可以包括在每個查詢的方式。

我嘗試了所有的LINQ查詢

public static IEnumerable<T> FrontEnd<T>(this DbSet<T> dbSet) where T : class { 
    return dbSet.Cast<IPublishable>().Where(x => x.IsPublished ...).Cast<T>(); 
} 

創建擴展方法,並使用了諸如t他...

context.Objects1.FrontEnd().Where(x => ...).OrderBy(... 

但是我得到的錯誤「LINQ到實體僅支持鑄造EDM原始或枚舉類型」

我新的EF,所以任何信息將是一個很大的幫助。 謝謝

+0

我認爲某種[表達](http://msdn.microsoft.com/en-us/library/bb397951.aspx)可以爲這個創建。 – Romoku

+0

爲了完成類似的事情,我最終使用了動態LINQ。但是,這只是針對特定的數據子集,而不是您需要的「所有linq查詢」,所以我不確定它是否正是您想要的。 – Mansfield

+0

我認爲我正在尋找的真實答案是基於知識庫的應用程序和實體框架之間的臨時過程,我可以攔截查詢並在基礎上添加我在所有查詢中使用的子句 – JDandChips

回答

2

更新每個評論 - 這工作

public static IQueryable<T> FrontEnd<T>(this DbSet<T> dbSet) 
    where T : class, IPublishable 
{ 
    return dbSet.Where(x => x.IsPublished); 
} 

,並可以這樣使用:

context.Objects1.FrontEnd().Where(x => ...).OrderBy(... 

您可以嘗試這兩個選項之一:

public static IQueryable<dynamic> FrontEnd(this DbSet<dynamic> dbSet) 
{ 
    return dbSet.Where(x => (x as IPublishable).IsPublished); 
} 

public static IQueryable<T> FrontEnd<T>(this DbSet<T> dbSet) 
    where T : class, IPublishable 
{ 
    return dbSet.Where(x => x.IsPublished); 
} 

注:

第一選項使用動態的,所以是與你必須指定在調用前端() 例如類型第二個選項較慢

context.Objects1.FrontEnd<Objects1>().Where(x => ...).OrderBy(... 
+0

這非常好,一直在尋找!我實現了建議2,發現我不需要指定''......查看你給出的例子和我的代碼,我確定它們是相同的?不是我在抱怨:) – JDandChips

0

我認爲LINQ to Entities不知道如何匹配轉換操作符到SQL請求。作爲一個建議,你可以嘗試類似這樣的:

IEnumerable<IPublishable> ReadPublishable(Expression<Func<DomainModelType, bool>> condition) 

該表達式充當謂詞。所以你傳遞給ReadPublishable函數一個謂詞來過濾你需要的IPublishable對象。我嘗試了成功,但只是簡單的謂詞,所以我不知道如果你使用「is」或「as」操作符是否有效。

相關問題