2012-12-04 57 views
23

我有一些實體框架表,我已經使用它們的部分類支持接口IHistoricEntityIHistoricEntityActiveToDatetime?財產。這裏演員在哪裏? LINQ to Entities只支持鑄造實體數據模型基本類型

// Auto generated LINQ to Entities domain service: 
[EnableClientAccess()] 
public partial class ProductService : LinqToEntitiesDomainService<ProductDBEntities> 
{ 
    public IQueryable<ANALYSIS_CODES> GetANALYSIS_CODES() 
    { 
     return this.ObjectContext.ANALYSIS_CODES; 
    } 
... 
} 

// My Partial class to add interface 
public partial class ANALYSIS_CODES : IHistoricEntity 
{} 

我試圖重構該工作代碼的方法:

List<ANALYSIS_CODE> filtered = (from rec in ps.GetANALYSIS_CODES() where rec.ActiveTo == null select rec).ToList() 

像這樣:

private List<T> Filter<T>(IQueryable<T> queryable) where T : IHistoricEntity 
{ 
    return (from rec in queryable where rec.ActiveTo == null select rec).ToList(); 
} 

// called like this: 
List<ANALYSIS_CODE> filtered = Filter(ps.GetANALYSIS_CODES()); 

這使得在ToList此異常:

無法將類型'ANALYSIS_CODES'轉換爲鍵入'IHistoricEntity'。 LINQ to Entities僅支持投射實體數據模型基元類型。

但我在哪裏要求它投射到IHistoricEntity?我已經明確表示T必須支持IHistoricEntity

+0

您是否嘗試過存放在變量的查詢和在ToListing之前在調試器中檢查它的表達屬性?這應該顯示你演員的位置。 – wizzardmr42

+0

這裏沒有什麼用處,當我嘗試擴展結果時,我得到了異常。 – weston

+0

您是否嘗試明確訪問.expression屬性?它在調試器中並不總是可見的,但您應該能夠手動輸入它。另外,在調試器中嘗試query.ToString(),因爲這可能會給出一個線索(適用於Linq to SQL,不要認爲我已經使用實體嘗試過) – wizzardmr42

回答

44

rec.ActiveTo引用在您的界面中定義的屬性。因此,在能夠訪問該屬性之前,Linq需要將rec轉換爲IHistoricEntity

不要被例外.ToList()被提出來愚弄:LINQ查詢時才計算並執行需要記錄的時候,在這種情況下,當收集被改造成一個List<>

更新:我驗證@ HVD的評論,事實上,加入where T: class條款的改變從

System.Collections.Generic.List`1[MyType] 
    .Where(x => (Convert(x).ActiveTo == Convert(null))) 

LINQ的表達

System.Collections.Generic.List`1[MyType] 
    .Where(x => (x.ActiveTo == Convert(null))) 
+23

「因此,Linq需要將'rec'強制轉換爲' IHistoricEntity'才能夠訪問該屬性。「 - 幾乎,但不完全。通過在泛型參數中包含一個'class'約束來避免這個要求。當預先知道類型是參考類型時,轉換爲「IHistoricEntity」是一個no-op,並且不包括在內。 (因爲'T'可能是一個結構體,因此'cast可能是一個裝箱操作。) – hvd

+2

@hvd很好,謝謝你們,'T:class,IHistoricEntity'在這裏做了訣竅。這對啓動來說非常有意義! – weston

+0

哇!我成立了幾天的解決方案! T:課堂修復它!非常感謝!!! 1 –

相關問題