Bekannte Probleme von und Überlegungen zu LINQ to Entities
Dieser Abschnitt enthält Informationen zu bekannten Problemen bei LINQ to Entities -Abfragen.
Fehlende Sortierung
Keine Unterstützung von ganzen Zahlen ohne Vorzeichen
Typkonvertierungsfehler
Keine Unterstützung von Verweisen auf nicht skalare Variablen
Geschachtelte Abfragen schlagen mit SQL Server 2000 möglicherweise fehl
Projizieren auf einen anonymen Typ
Fehlende Sortierung
Beim Projizieren von Spalten in einen anonymen Typ geht die Sortierung in einigen Abfragen verloren, die für eine SQL Server 2005 -Datenbank mit dem Kompatibilitätsgrad "80" ausgeführt werden. Dies kann vorkommen, wenn ein Spaltenname in der Sortierliste einem Spaltennamen im Selektor entspricht, wie im folgenden Beispiel dargestellt:
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
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);
}
Keine Unterstützung von ganzen Zahlen ohne Vorzeichen
Sie können in einer LINQ to Entities -Abfrage keine ganze Zahl ohne Vorzeichen angeben, da das Entity Framework keine ganzen Zahlen ohne Vorzeichen unterstützt. Wenn Sie eine ganze Zahl ohne Vorzeichen angeben, wird bei der Übersetzung des Abfrageausdrucks eine ArgumentException-Ausnahme ausgelöst, wie im folgenden Beispiel dargestellt. In diesem Beispiel wird die Bestellung mit der ID 48000 abgefragt.
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
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: {0}", ex.Message);
}
}
Typkonvertierungsfehler
Wenn Sie in Visual Basic einer Eigenschaft mithilfe der CByte-Funktion eine Spalte des SQL Server-Bittyps mit dem Wert 1 zuordnen, wird eine SqlException mit der Meldung "Arithmetischer Überlauffehler" ausgelöst. Im folgenden Beispiel wird in der AdventureWorks-Beispieldatenbank die Product.MakeFlag-Spalte abgefragt, und beim Durchlaufen der Abfrageergebnisse wird eine Ausnahme ausgelöst.
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
Keine Unterstützung von Verweisen auf nicht skalare Variablen
Verweise auf eine nicht skalare Variable, beispielsweise eine Entität, in einer Abfrage werden nicht unterstützt. Bei der Ausführung einer solchen Abfrage wird eine NotSupportedException-Ausnahme mit der Meldung ausgelöst, dass ein konstanter Wert des Typs EntityType nicht erstellt werden kann, weil im gegebenen Kontext nur primitive Typen, beispielsweise Int32, Zeichenfolge und Guid unterstützt werden.
Hinweis: |
---|
Verweise auf eine Auflistung von skalaren Variablen werden unterstützt. |
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
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: ", name);
}
}
catch (NotSupportedException ex)
{
Console.WriteLine(ex.Message);
}
}
Geschachtelte Abfragen schlagen mit SQL Server 2000 möglicherweise fehl
Mit SQL Server 2000 schlagen LINQ to Entities-Abfragen möglicherweise fehl, wenn sie geschachtelte Transact-SQL-Abfragen erzeugen, die drei oder mehr Ebenen tief sind.
Projizieren auf einen anonymen Typ
Wenn Sie den anfänglichen Abfragepfad so definieren, dass mithilfe der Include-Methode verknüpfte Objekte in ObjectQuery eingeschlossen werden, und dann LINQ verwenden, um die zurückgegebenen Objekte auf einen anonymen Typ zu projizieren, werden die in der Include-Methode angegebenen Objekte nicht in die Abfrageergebnisse eingeschlossen.
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 resultWithoutRelatedObjects =
context.Contacts.Include("SalesOrderHeaders").Select(c => new { c }).FirstOrDefault();
if (resultWithoutRelatedObjects.c.SalesOrderHeaders.Count == 0)
{
Console.WriteLine("No orders are included.");
}
}
Um verknüpfte Objekte abzurufen, projizieren Sie die zurückgegebenen Typen nicht auf einen anonymen Typ.
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
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.");
}
}