Bekende problemen en overwegingen in LINQ naar entiteiten
Deze sectie bevat informatie over bekende problemen met LINQ naar entiteiten-query's.
LINQ-query's die niet in de cache kunnen worden opgeslagen
Vanaf .NET Framework 4.5 worden LINQ-query's naar entiteiten automatisch in de cache opgeslagen. LINQ op entiteitenquery's die de operator toepassen op in-memory verzamelingen, worden echter niet automatisch in de Enumerable.Contains
cache opgeslagen. Het parameteriseren van in-memory verzamelingen in gecompileerde LINQ-query's is ook niet toegestaan.
Bestelgegevens verloren
Als u kolommen projecteert in een anoniem type, gaan bestelgegevens verloren in sommige query's die worden uitgevoerd op een SQL Server 2005-database die is ingesteld op een compatibiliteitsniveau van '80'. Dit gebeurt wanneer een kolomnaam in de order-by-lijst overeenkomt met een kolomnaam in de selector, zoals wordt weergegeven in het volgende voorbeeld:
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
Niet-ondertekende gehele getallen worden niet ondersteund
Het opgeven van een niet-ondertekend geheel getal in een LINQ naar entiteiten-query wordt niet ondersteund omdat het Entity Framework geen niet-ondertekende gehele getallen ondersteunt. Als u een geheel getal zonder teken opgeeft, wordt er een ArgumentException uitzondering gegenereerd tijdens de vertaling van de query-expressie, zoals wordt weergegeven in het volgende voorbeeld. In dit voorbeeld wordt een query uitgevoerd voor een order met id 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: {0}", 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
Typeconversiefouten
Wanneer in Visual Basic een eigenschap is toegewezen aan een kolom van het SQL Server-bittype met een waarde van 1 met behulp van de CByte
functie, wordt er een SqlException foutbericht 'Rekenkundige overloopfout' gegenereerd. In het volgende voorbeeld wordt de Product.MakeFlag
kolom in de AdventureWorks-voorbeelddatabase opgevraagd en er wordt een uitzondering gegenereerd wanneer de queryresultaten worden overschreven.
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
Verwijzingen naar niet-scalaire variabelen worden niet ondersteund
Het verwijzen naar een niet-scalaire variabelen, zoals een entiteit, in een query wordt niet ondersteund. Wanneer een dergelijke query wordt uitgevoerd, wordt er een NotSupportedException uitzondering gegenereerd met een bericht met de tekst 'Kan geen constante waarde van het type EntityType
maken. In deze context worden alleen primitieve typen ('zoals Int32, String en Guid') ondersteund.
Notitie
Verwijzen naar een verzameling scalaire variabelen wordt ondersteund.
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);
}
}
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
Geneste query's mislukken mogelijk met SQL Server 2000
Met SQL Server 2000 kunnen LINQ naar entiteiten-query's mislukken als ze geneste Transact-SQL-query's produceren die drie of meer niveaus diep zijn.
Projecteren naar een anoniem type
Als u het eerste querypad definieert om gerelateerde objecten op te nemen met behulp van de Include methode op de ObjectQuery<T> en vervolgens LINQ gebruikt om de geretourneerde objecten te projecteren op een anoniem type, worden de objecten die zijn opgegeven in de include-methode, niet opgenomen in de queryresultaten.
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
Als u gerelateerde objecten wilt ophalen, projecteert u geen geretourneerde typen naar een anoniem type.
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