本節提供 LINQ to Entities 查詢已知問題的相關信息。
無法快取的LINQ查詢
從 .NET Framework 4.5 開始,會自動快取 LINQ to Entities 查詢。 不過,將 Enumerable.Contains
運算子套用至記憶體集合的 LINQ to Entities 查詢不會自動快取。 此外,不允許在編譯的 LINQ 查詢中參數化記憶體內部集合。
訂單信息遺失
將欄位投影至匿名類型,會導致某些執行於設定了「80」相容性層級的 SQL Server 2005 資料庫的查詢中,排序資訊遺失。 當依順序列表的數據行名稱符合選取器中的數據行名稱時,就會發生這種情況,如下列範例所示:
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
// Ordering information is lost when executed against a SQL Server 2005
// database running with a compatibility level of "80".
var results = context.Contacts.SelectMany(c => c.SalesOrderHeaders)
.OrderBy(c => c.SalesOrderDetails.Count)
.Select(c => new { c.SalesOrderDetails.Count });
foreach (var result in results)
Console.WriteLine(result.Count);
}
Using context As New AdventureWorksEntities()
' Ordering information is lost when executed against a SQL Server 2005
' database running with a compatibility level of "80".
Dim results = context.Contacts.SelectMany(Function(c) c.SalesOrderHeaders) _
.OrderBy(Function(c) c.SalesOrderDetails.Count) _
.Select(Function(c) New With {c.SalesOrderDetails.Count})
For Each result In results
Console.WriteLine(result.Count)
Next
End Using
不支援不帶正負號的整數
不支援在 LINQ to Entities 查詢中指定不帶正負號的整數類型,因為 Entity Framework 不支援無符號整數。 如果您指定不帶正負號的整數,查詢表達式轉譯期間將會擲回 ArgumentException 例外狀況,如下列範例所示。 此範例會查詢標識碼為 48000 的訂單。
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
uint s = UInt32.Parse("48000");
IQueryable<SalesOrderDetail> query = from sale in context.SalesOrderDetails
where sale.SalesOrderID == s
select sale;
// NotSupportedException exception is thrown here.
try
{
foreach (SalesOrderDetail order in query)
Console.WriteLine("SalesOrderID: " + order.SalesOrderID);
}
catch (NotSupportedException ex)
{
Console.WriteLine($"Exception: {ex.Message}");
}
}
Using context As New AdventureWorksEntities()
Dim saleId As UInteger = UInt32.Parse("48000")
Dim query = _
From sale In context.SalesOrderDetails _
Where sale.SalesOrderID = saleId _
Select sale
Try
' NotSupportedException exception is thrown here.
For Each order As SalesOrderDetail In query
Console.WriteLine("SalesOrderID: " & order.SalesOrderID)
Next
Catch ex As NotSupportedException
Console.WriteLine("Exception: " + ex.Message)
End Try
End Using
類型轉換錯誤
在 Visual Basic 中,當屬性使用 CByte
函式對應至值為 1 的 SQL Server 位類型數據行時,會擲回具有「算術溢位錯誤」訊息的 SqlException。 下列範例會查詢 AdventureWorks 範例資料庫中的 Product.MakeFlag
欄位,並在遍歷查詢結果時引發例外。
Using context As New AdventureWorksEntities()
Dim productsList = _
From product In context.Products _
Select CByte(product.MakeFlag)
' Throws an SqlException exception with a "Arithmetic overflow error
' for data type tinyint" message when a value of 1 is iterated over.
For Each makeFlag In productsList
Console.WriteLine(makeFlag)
Next
End Using
不支援參考非標量變數
不支援在查詢中參考非純量變數,例如實體。 當這類查詢執行時,會擲回 NotSupportedException 例外狀況,並顯示「無法建立類型的常數值 EntityType
。 在此內容中只支援基本類型 (例如 Int32、String 和 Guid')。
備註
支持參考純量變數集合。
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
Contact contact = context.Contacts.FirstOrDefault();
// Referencing a non-scalar closure in a query will
// throw an exception when the query is executed.
IQueryable<string> contacts = from c in context.Contacts
where c == contact
select c.LastName;
try
{
foreach (string name in contacts)
{
Console.WriteLine($"Name: ");
}
}
catch (NotSupportedException ex)
{
Console.WriteLine(ex.Message);
}
}
Using context As New AdventureWorksEntities()
Dim contact As Contact = context.Contacts.FirstOrDefault()
' Referencing a non-scalar closure in a query will
' throw an exception when the query is executed.
Dim contacts = From c In context.Contacts _
Where c.Equals(contact) _
Select c.LastName
Try
For Each name As String In contacts
Console.WriteLine("Name: ", name)
Next
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Using
巢狀查詢可能會因為 SQL Server 2000 而失敗
使用 SQL Server 2000 時,如果 LINQ to Entities 查詢產生巢狀 Transact-SQL 查詢,其深度為三個或多個層級,則可能會失敗。
投影至匿名類型
如果您在 Include 上使用 ObjectQuery<T> 方法定義包含相關物件的初始查詢路徑,然後使用 LINQ 將傳回的物件投影至匿名類型,則 include 方法中指定的物件不會包含在查詢結果中。
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
var resultWithoutRelatedObjects =
context.Contacts.Include("SalesOrderHeaders").Select(c => new { c }).FirstOrDefault();
if (resultWithoutRelatedObjects.c.SalesOrderHeaders.Count == 0)
{
Console.WriteLine("No orders are included.");
}
}
Using context As New AdventureWorksEntities()
Dim resultWithoutRelatedObjects = context.Contacts. _
Include("SalesOrderHeaders"). _
Select(Function(c) New With {c}).FirstOrDefault()
If resultWithoutRelatedObjects.c.SalesOrderHeaders.Count = 0 Then
Console.WriteLine("No orders are included.")
End If
End Using
若要取得相關物件,請勿將傳回的類型投影到匿名型別。
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
var resultWithRelatedObjects =
context.Contacts.Include("SalesOrderHeaders").Select(c => c).FirstOrDefault();
if (resultWithRelatedObjects.SalesOrderHeaders.Count != 0)
{
Console.WriteLine("Orders are included.");
}
}
Using context As New AdventureWorksEntities()
Dim resultWithRelatedObjects = context.Contacts. _
Include("SalesOrderHeaders"). _
Select(Function(c) c).FirstOrDefault()
If resultWithRelatedObjects.SalesOrderHeaders.Count <> 0 Then
Console.WriteLine("Orders are included.")
End If
End Using