Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
LINQ to SQL übersetzt Standardabfrageoperatoren in SQL-Befehle. Der Abfrageprozessor der Datenbank bestimmt die Ausführungssemantik der SQL-Übersetzung.
Standardabfrageoperatoren werden für Sequenzen definiert. Eine Sequenz wird sortiert und basiert auf der Referenzidentität für jedes Element der Sequenz. Weitere Informationen finden Sie unter Standard Query Operators Overview (C#) oder Standard Query Operators Overview (Visual Basic).
SQL behandelt in erster Linie ungeordnete Wertesätze. Die Sortierung ist in der Regel ein explizit angegebener Nachbearbeitungsvorgang, der auf das Endergebnis einer Abfrage und nicht auf Zwischenergebnisse angewendet wird. Die Identität wird durch Werte definiert. Aus diesem Grund befassen sich SQL-Abfragen mit Multisets (so genannten bags) und nicht mit Sätzen.
In den folgenden Absätzen werden die Unterschiede zwischen den Standardabfrageoperatoren und deren SQL-Übersetzung für den SQL Server-Anbieter für LINQ to SQL beschrieben.
Operatorunterstützung
Verkettung
Die Concat Methode wird für sortierte Multisets definiert, bei denen die Reihenfolge des Empfängers und die Reihenfolge des Arguments identisch sind.
Concat funktioniert wie UNION ALL
bei den Multisets, gefolgt von der gemeinsamen Reihenfolge.
Der letzte Schritt ist die Sortierung in SQL, bevor Ergebnisse erstellt werden. Concat behält die Reihenfolge ihrer Argumente nicht bei. Um eine geeignete Reihenfolge sicherzustellen, müssen Sie die Ergebnisse von Concat explizit sortieren.
Überschneiden, außer Union
Die Intersect-Methode und die Except-Methode sind nur für Sätze gut definiert. Die Semantik für Multisets ist nicht definiert.
Die Union Methode wird für Multisets als ungeordnete Verkettung der Multisets definiert (effektiv das Ergebnis der UNION ALL-Klausel in SQL).
Take, Skip
Die Methoden Take und Skip sind nur für sortierte Sätze gut definiert. Die Semantik für ungeordnete Sätze oder Multisets ist nicht definiert.
Hinweis
Take und Skip bestimmte Einschränkungen aufweisen, wenn sie in Abfragen mit SQL Server 2000 verwendet werden. Weitere Informationen finden Sie im Eintrag "Überspringen und Übernehmen von Ausnahmen in SQL Server 2000" in der Problembehandlung.
Aufgrund von Einschränkungen bei der Sortierung in SQL versucht LINQ to SQL, die Sortierung des Arguments dieser Methoden auf das Ergebnis der Methode zu verschieben. Betrachten Sie beispielsweise die folgende LINQ to SQL-Abfrage:
var custQuery =
(from cust in db.Customers
where cust.City == "London"
orderby cust.CustomerID
select cust).Skip(1).Take(1);
Dim custQuery = _
From cust In db.Customers _
Where cust.City = "London" _
Order By cust.CustomerID _
Select cust Skip 1 Take 1
Die generierte SQL für diesen Code verschiebt die Sortierung wie folgt an das Ende:
SELECT TOP 1 [t0].[CustomerID], [t0].[CompanyName],
FROM [Customers] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT TOP 1 [t1].[CustomerID]
FROM [Customers] AS [t1]
WHERE [t1].[City] = @p0
ORDER BY [t1].[CustomerID]
) AS [t2]
WHERE [t0].[CustomerID] = [t2].[CustomerID]
))) AND ([t0].[City] = @p1)
ORDER BY [t0].[CustomerID]
Es wird offensichtlich, dass alle angegebenen Sortierungen konsistent sein müssen, wenn Take und Skip miteinander verkettet werden. Andernfalls sind die Ergebnisse nicht definiert.
Sowohl Take als auch Skip sind für nicht-negative, konstante, integrale Argumente auf der Grundlage der Spezifikation des Standardabfrage-Operators gut definiert.
Operatoren ohne Übersetzung
Die folgenden Methoden werden von LINQ to SQL nicht übersetzt. Der häufigste Grund ist der Unterschied zwischen ungeordneten Multisets und Sequenzen.
Betriebspersonal | Grund |
---|---|
TakeWhile, SkipWhile | SQL-Abfragen werden auf Multisets und nicht auf Sequenzen ausgeführt.
ORDER BY muss die letzte Klausel sein, die auf die Ergebnisse angewendet wird. Aus diesem Grund gibt es keine allgemeine Übersetzung für diese beiden Methoden. |
Reverse | Die Übersetzung dieser Methode ist für einen sortierten Satz möglich, wird aber derzeit nicht von LINQ in SQL übersetzt. |
Last, LastOrDefault | Die Übersetzung dieser Methoden ist für einen sortierten Satz möglich, wird aber derzeit nicht von LINQ in SQL übersetzt. |
ElementAt, ElementAtOrDefault | SQL-Abfragen werden für Multisets ausgeführt, nicht für indizierbare Sequenzen. |
DefaultIfEmpty (Überladung mit Standard-arg) | Im Allgemeinen kann ein Standardwert nicht für ein beliebiges Tupel angegeben werden. NULL-Werte für Tupel sind in einigen Fällen durch äußere Joins möglich. |
Ausdrucksübersetzung
Null-Semantik
LINQ to SQL erzwingt keine Nullvergleichsemantik für SQL. Vergleichsoperatoren werden syntaktisch in ihre SQL-Entsprechungen übersetzt. Aus diesem Grund spiegelt die Semantik die von Server- oder Verbindungseinstellungen definierte SQL-Semantik wider. Beispielsweise werden zwei NULL-Werte unter den Standardmäßigen SQL Server-Einstellungen als ungleich angesehen, aber Sie können die Einstellungen ändern, um die Semantik zu ändern. LINQ to SQL berücksichtigt beim Übersetzen von Abfragen keine Servereinstellungen.
Ein Vergleich mit dem Literal null wird in die entsprechende SQL-Version (is null
oder is not null
) übersetzt.
Der Wert von null
in der Zusammenstellung wird von SQL-Server definiert. LINQ to SQL ändert die Sortierung nicht.
Aggregate
Die Aggregatmethode Sum des Standardabfrageoperators wertet für eine leere Sequenz oder für eine Sequenz, die nur Nullen enthält, auf Null aus. In LINQ to SQL bleiben die Semantik von SQL unverändert, und Sum wird als null
ausgewertet anstelle von null, wenn es sich um eine leere Sequenz oder eine Sequenz handelt, die nur Nullen enthält.
SQL-Einschränkungen für Zwischenergebnisse gelten für Aggregate in LINQ to SQL. Die Sum 32-Bit-Ganzzahlmengen werden nicht mit 64-Bit-Ergebnissen berechnet. Ein Überlauf kann bei einer LINQ to SQL-Übersetzung von Sum auftreten, selbst wenn die Implementierung des Standardabfrageoperators keinen Überlauf für die entsprechende in-memory-Sequenz verursacht.
Ebenso wird die LINQ to SQL-Übersetzung von Average von Ganzzahlenwerten als integer
berechnet, nicht als double
.
Entitätsargumente
LINQ to SQL ermöglicht die Verwendung von Entitätstypen in den GroupBy und OrderBy methoden. Bei der Übersetzung dieser Operatoren wird die Verwendung eines Arguments eines bestimmten Typs als gleichwertig dazu betrachtet, alle Mitglieder dieses Typs anzugeben. Der folgende Code ist z. B. gleichwertig:
db.Customers.GroupBy(c => c);
db.Customers.GroupBy(c => new { c.CustomerID, c.ContactName });
db.Customers.GroupBy(Function(c) c)
db.Customers.GroupBy(Function(c) New With {c.CustomerID, _
c.ContactName})
Gleichstellbare/ vergleichbare Argumente
Die Gleichheit von Argumenten ist bei der Implementierung der folgenden Methoden erforderlich:
LINQ to SQL unterstützt Gleichheit und Vergleich für flache Argumente, jedoch nicht für Argumente, die Sequenzen sind oder diese enthalten. Ein flaches Argument ist ein Typ, der einer SQL-Zeile zugeordnet werden kann. Eine Projektion von einem oder mehreren Entitätstypen, bei denen statisch festgestellt werden kann, dass sie keine Sequenz enthalten, wird als flaches Argument betrachtet.
Es folgen Beispiele für flache Argumente:
db.Customers.Select(c => c);
db.Customers.Select(c => new { c.CustomerID, c.City });
db.Orders.Select(o => new { o.OrderID, o.Customer.City });
db.Orders.Select(o => new { o.OrderID, o.Customer });
db.Customers.Select(Function(c) c)
db.Customers.Select(Function(c) New With {c.CustomerID, c.City})
db.Orders.Select(Function(o) New With {o.OrderID, o.Customer.City})
db.Orders.Select(Function(o) New With {o.OrderID, o.Customer})
Im Folgenden sind Beispiele für nicht flache (hierarchische) Argumente aufgeführt:
// In the following line, c.Orders is a sequence.
db.Customers.Select(c => new { c.CustomerID, c.Orders });
// In the following line, the result has a sequence.
db.Customers.GroupBy(c => c.City);
' In the following line, c.Orders is a sequence.
db.Customers.Select(Function(c) New With {c.CustomerID, c.Orders})
' In the following line, the result has a sequence.
db.Customers.GroupBy(Function(c) c.City)
Übersetzung der Visual Basic-Funktion
Die folgenden Hilfsfunktionen, die vom Visual Basic-Compiler verwendet werden, werden in entsprechende SQL-Operatoren und -Funktionen übersetzt:
CompareString
DateTime.Compare
Decimal.Compare
IIf (in Microsoft.VisualBasic.Interaction)
Konvertierungsmethoden:
ToBoolean
ToSByte
ToByte
ToChar
ToCharArrayRankOne
ToDate
ToDecimal
ToDouble
ToInteger
ToUInteger
ToLong
ToULong
ToShort
ToUShort
ToSingle
ToString
Vererbungsunterstützung
Einschränkungen bei der Vererbungsabbildung
Weitere Informationen finden Sie unter Anleitung: Zuordnung von Vererbungshierarchien.
Vererbung in Abfragen
C#-Umwandlungen werden nur in Projektionen unterstützt. An anderer Stelle verwendete Umwandlungen werden nicht übersetzt, sonder ignoriert. Abgesehen von SQL-Funktionsnamen führt SQL tatsächlich nur das Äquivalent der Common Language Runtime (CLR) Convertdurch. Das heißt, SQL kann den Wert eines Typs in einen anderen ändern. Es gibt keine Entsprechung zu CLR-Umwandlungen, da es kein Konzept für die Neuinterpretation der gleichen Bits als die eines anderen Typs gibt. Aus diesem Grund funktioniert eine C#-Umwandlung nur lokal. Eine Remoteausführung ist nicht möglich.
Die Operatoren is
und as
, und die GetType
Methode sind nicht auf den Select
Operator beschränkt. Sie können auch in anderen Abfrageoperatoren verwendet werden.
SQL Server 2008-Unterstützung
Ab .NET Framework 3.5 SP1 unterstützt LINQ to SQL die Zuordnung zu neuen Datums- und Uhrzeittypen, die mit SQL Server 2008 eingeführt wurden. Es gibt jedoch einige Einschränkungen für die LINQ to SQL-Abfrageoperatoren, die Sie beim Betrieb mit Werten verwenden können, die diesen neuen Typen zugeordnet sind.
Nicht unterstützte Abfrageoperatoren
Die folgenden Abfrageoperatoren werden für Werte, die den neuen SQL Server-Datums- und Uhrzeittypen zugeordnet sind, nicht unterstützt: DATETIME2
, , , DATE
TIME
und DATETIMEOFFSET
.
Aggregate
Average
LastOrDefault
OfType
Sum
Weitere Informationen zum Zuordnen zu diesen SQL Server-Datums- und -Uhrzeittypen finden Sie unterSQL-CLR Typzuordnung.
SQL Server 2005-Unterstützung
LINQ to SQL unterstützt nicht die folgenden SQL Server 2005-Features:
Gespeicherte Prozeduren, die für SQL CLR geschrieben wurden.
Benutzerdefinierter Typ.
XML-Abfragefunktionen.
SQL Server 2000-Unterstützung
Die folgenden SQL Server 2000-Einschränkungen (im Vergleich zu Microsoft SQL Server 2005) wirken sich auf LINQ to SQL-Unterstützung aus.
Cross Apply-Operator und Outer Apply-Operator
Diese Operatoren sind in SQL Server 2000 nicht verfügbar. LINQ to SQL versucht, eine Reihe von Umformulierungen vorzunehmen, um sie durch passende Joins zu ersetzen.
Cross Apply
und Outer Apply
werden für Beziehungsnavigationen generiert. Der Satz von Abfragen, für die solche Umschreibungen möglich sind, ist nicht gut definiert. Aus diesem Grund ist der minimale Satz von Abfragen, die für SQL Server 2000 unterstützt werden, der Satz, der keine Beziehungsnavigation umfasst.
text / ntext
Die Datentypen text
/ ntext
können in bestimmten Abfragevorgängen für varchar(max)
/ nvarchar(max)
, die von Microsoft SQL Server 2005 unterstützt werden, nicht verwendet werden.
Für diese Einschränkung steht keine Lösung zur Verfügung. Insbesondere können Sie kein Distinct()
für ein Ergebnis verwenden, das Mitglieder enthält, die den text
- oder ntext
-Spalten zugeordnet sind.
Verhalten ausgelöst durch geschachtelte Abfragen
Die Bindung von SQL Server 2000 (bis einschließlich SP4) weist einige Eigenheiten auf, die durch geschachtelte Abfragen ausgelöst werden. Der Satz von SQL-Abfragen, die diese Idiosyncrasies auslösen, ist nicht gut definiert. Aus diesem Grund können Sie den Satz von LINQ to SQL-Abfragen nicht definieren, die SQL Server-Ausnahmen verursachen können.
Skip-Operator und Take-Operator
Take und Skip bestimmte Einschränkungen aufweisen, wenn sie in Abfragen mit SQL Server 2000 verwendet werden. Weitere Informationen finden Sie im Eintrag "Überspringen und Übernehmen von Ausnahmen in SQL Server 2000" in der Problembehandlung.
Objektmaterialisierung
Die Materialisierung erstellt CLR-Objekte aus Zeilen, die von einer oder mehreren SQL-Abfragen zurückgegeben werden.
Die folgenden Aufrufe werden lokal als Teil der Materialisierung ausgeführt :
Erbauer
ToString
Methoden für ProjektionenTypumwandlungen in Projektionen
Methoden, die der AsEnumerable Methode folgen, werden lokal ausgeführt. Diese Methode verursacht keine sofortige Ausführung.
Sie können einen
struct
als Rückgabetyp eines Abfrageergebnisses oder als Element des Ergebnistyps verwenden. Entitäten müssen Klassen sein. Anonyme Typen werden als Klasseninstanzen materialisiert, aber benannte Strukturen (Nichtentitäten) können in der Projektion verwendet werden.Ein Element des Rückgabetyps eines Abfrageergebnisses kann vom Typ IQueryable<T>sein. Er wird als lokale Auflistung materialisiert.
Die folgenden Methoden verursachen die sofortige Materialisierung der Sequenz, auf die die Methoden angewendet werden: