2013-08-26 54 views
12

我有一些代碼,最近從EF 4.2升級到EF 5.0(實際上是EF 4.4,因爲我在.Net 4.0上運行)。我發現我不得不改變我的查詢的語法,我很好奇爲什麼。讓我從問題開始。爲什麼EF 5.0在編譯爲sql時不支持這種EF 4.x LINQ語法?

我有一個由客戶端定期填充的EventLog表。對於每個事件日誌,在報表中創建一個條目。這是定期運行的查詢,用於發現沒有報表表格中的條目的任何事件日誌。我在EF 4.2中使用的查詢是:

from el in _repository.EventLogs 
where !_repository.Reports.Any(p => p.EventLogID == el.EventlogID) 

由於升級到EF 5.0我會在運行時出現以下錯誤:

System.NotSupportedException:無法創建 類型的恆定值「命名空間。報告'。在此上下文中僅支持基本類型或枚舉類型 。

我發現用連接語法重寫它解決了問題。在EF 5.0以下工程和大致等價的:

from eventLog in _repository.EventLogs 
join report in _repository.Reports on eventLog.EventlogID equals report.EventLogID into alreadyReported 
where !alreadyReported.Any() 

有些人可能對第一次查詢的混合語法/風格不同的意見,但我真的在更感興趣,爲什麼這一點。 EF 4.2編譯器可以爲原始查詢生成SQL,但EF 5.0拒絕,這似乎很奇怪。這是我缺少的一個設置還是隻是收緊兩者之間的約束?這是爲什麼發生?

+0

就我個人而言,我認爲它更像一個查詢與加入可讀性。 –

+1

您可以測試這個,而不是從_repository.EventLogs el中刪除,其中_repository.Reports.All(p => p.EventLogID!= el.EventlogID )'? –

+0

嘿,金,我試過了,得到了同樣的結果。我甚至試過:!_repository.OntarioReports.Any(p => 5 == 5)。這似乎是我可以說的混合語法。 –

回答

2

的問題是由你的倉庫返回的類型引起的;當_repository.Reports不是IQueryable<T>時可以複製問題。在這種情況下,Reports被認爲是一個非標量變量;順便說一句,在LINQ中是不允許的。請參閱Referencing Non-Scalar Variables Not Supported

對於您爲什麼第二個查詢起作用的問題,它基本上是以下擴展方法IQueryable<T>,該組與IEnumerable<TInner>連接。

public static IQueryable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
    this IQueryable<TOuter> outer,IEnumerable<TInner> inner, 
    Expression<Func<TOuter, TKey>> outerKeySelector, 
    Expression<Func<TInner, TKey>> innerKeySelector, 
    Expression<Func<TOuter, IEnumerable<TInner>, TResult>> resultSelector) 

它只接受外部和內部的鍵選擇器的表達式(而不是引用非標量變量);其中上述約束條件不適用。

注:如果_repository.ReportsIQueryable<T>第一個查詢將工作;因爲EF將正確構建表達式樹並執行相應的SQL。

0

只是爲了好奇的緣故,你嘗試過將

from el in _repository.EventLogs 
where !_repository.Reports.Any(p => p.EventLogID == el.EventlogID) 

from el in _repository.EventLogs 
where !_repository.Reports.Where(p => p.EventLogID == el.EventlogID).Any(); 

from el in _repository.EventLogs 
where !_repository.Reports.Where(p => p.EventLogID == el.EventlogID).Count() > 0; 
+1

不應該這是一個評論? –

+0

這些都產生相同的行爲。 –