Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of mappen te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen om mappen te wijzigen.
LINQ naar SQL vertaalt Standard-queryoperators naar SQL-opdrachten. De queryprocessor van de database bepaalt de uitvoeringssemantiek van SQL-vertaling.
Standaardqueryoperators worden gedefinieerd op basis van reeksen. Een reeks wordt geordend en is afhankelijk van referentie-identiteit voor elk element van de reeks. Zie Overzicht van Standard-queryoperators (C#) of Overzicht van Standard-queryoperators (Visual Basic)voor meer informatie.
SQL behandelt voornamelijk niet-geordende sets van waarden. Ordenen is doorgaans een expliciete, naverwerkingsbewerking die wordt toegepast op het uiteindelijke resultaat van een query in plaats van op tussenliggende resultaten. Identiteit wordt gedefinieerd door waarden. Daarom worden SQL-query's begrepen als werkend met multisets (multisets) in plaats van sets.
In de volgende alinea's worden de verschillen beschreven tussen de Standard-queryoperators en de SQL-vertaling voor de SQL Server-provider voor LINQ naar SQL.
Operatorondersteuning
Concat
De Concat methode wordt gedefinieerd voor geordende multisets waarbij de volgorde van de ontvanger en de volgorde van het argument hetzelfde zijn.
Concat werkt als UNION ALL boven de multisets gevolgd door de gemeenschappelijke volgorde.
De laatste stap is het ordenen in SQL voordat de resultaten worden geproduceerd. Concat behoudt de volgorde van de argumenten niet. Om de juiste volgorde te garanderen, moet u de resultaten van Concat expliciet ordenen.
Kruispunt, Behalve, Vereniging
De Intersect en Except methoden zijn alleen goed gedefinieerd voor sets. De semantiek van multiverzamelingen is niet gedefinieerd.
De Union methode is gedefinieerd voor multisets als de niet-geordende concatenatie van de multisets (effectief het resultaat van de UNION ALL-clausule in SQL).
Neem, Overslaan
Take en Skip methoden zijn alleen goed gedefinieerd voor geordende verzamelingen. De semantiek voor niet-geordende sets of multisets is niet gedefinieerd.
Opmerking
Take en Skip bepaalde beperkingen hebben wanneer ze worden gebruikt in query's voor SQL Server 2000. Voor meer informatie, zie de vermelding 'Skip and Take Exceptions in SQL Server 2000' (Uitzonderingen overslaan en maken in SQL Server 2000) in Probleemoplossing.
Vanwege beperkingen voor het ordenen in SQL probeert LINQ naar SQL de volgorde van het argument van deze methoden te verplaatsen naar het resultaat van de methode. Denk bijvoorbeeld aan de volgende LINQ naar SQL-query:
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
De gegenereerde SQL voor deze code verplaatst de volgorde als volgt naar het einde:
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]
Het wordt duidelijk dat alle opgegeven volgorde consistent moet zijn wanneer Take en Skip aan elkaar zijn gekoppeld. Anders zijn de resultaten niet gedefinieerd.
Beide Take en Skip zijn goed gedefinieerd voor niet-negatieve, constante integrale argumenten op basis van de standaardqueryoperatorspecificatie.
Operators zonder vertaling
De volgende methoden worden niet vertaald door LINQ naar SQL. De meest voorkomende reden is het verschil tussen niet-geordende multisets en reeksen.
| Bedieners | Beredenatie |
|---|---|
| TakeWhile, SkipWhile | SQL-query's worden uitgevoerd op meerderesets, niet op reeksen.
ORDER BY moet de laatste component zijn die op de resultaten wordt toegepast. Daarom is er geen vertaling voor algemeen gebruik voor deze twee methoden. |
| Reverse | Vertaling van deze methode is mogelijk voor een geordende set, maar wordt momenteel niet vertaald door LINQ naar SQL. |
| Last, LastOrDefault | Vertaling van deze methoden is mogelijk voor een geordende set, maar wordt momenteel niet vertaald door LINQ naar SQL. |
| ElementAt, ElementAtOrDefault | SQL-query's worden uitgevoerd op meerderesets, niet op indexeerbare reeksen. |
| DefaultIfEmpty (overbelasting met standaard arg) | Over het algemeen kan een standaardwaarde niet worden opgegeven voor een willekeurige tuple. Null-waarden voor tuples zijn in sommige gevallen mogelijk via outer joins. |
Uitdrukkingvertaling
Null-semantiek
LINQ naar SQL legt geen null-vergelijkingssemantiek op voor SQL. Vergelijkingsoperatoren worden syntactisch vertaald naar hun SQL-equivalenten. Daarom weerspiegelen de semantiek SQL-semantiek die zijn gedefinieerd door server- of verbindingsinstellingen. Twee null-waarden worden bijvoorbeeld als ongelijk beschouwd onder de standaardINSTELLINGEN van SQL Server, maar u kunt de instellingen wijzigen om de semantiek te wijzigen. LINQ naar SQL houdt geen rekening met serverinstellingen wanneer query's worden vertaald.
Een vergelijking met de letterlijke null wordt vertaald naar de juiste SQL-versie (is null of is not null).
De waarde van null in sortering wordt gedefinieerd door SQL Server. LINQ naar SQL wijzigt de sortering niet.
Aggregaten
De statistische methode Sum Standard Query Operator evalueert naar nul voor een lege reeks of voor een reeks die alleen null-waarden bevat. In LINQ naar SQL blijft de semantiek van SQL ongewijzigd en Sum wordt geëvalueerd tot null in plaats van nul voor een lege reeks of voor een reeks die alleen nullen bevat.
SQL-beperkingen voor tussenliggende resultaten zijn van toepassing op aggregaties in LINQ naar SQL. De Sum van 32-bits gehele getalwaarden wordt niet berekend door gebruik te maken van 64-bits resultaten. Overloop kan optreden voor een LINQ naar SQL-vertaling van Sum, zelfs als de implementatie van de Standard-queryoperator geen overloop veroorzaakt voor de bijbehorende in-memory reeks.
Op dezelfde manier wordt de LINQ naar SQL-vertaling van gehele getallen Average berekend als een integer, en niet als een double.
Entiteitargumenten
LINQ naar SQL maakt het mogelijk om entiteitstypen te gebruiken in de GroupBy en OrderBy methoden. In de vertaling van deze operators wordt het gebruik van een argument van een type beschouwd als het equivalent van het opgeven van alle leden van dat type. De volgende code is bijvoorbeeld gelijk:
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})
Gelijkbare/vergelijkbare argumenten
Gelijkheid van argumenten is vereist bij de implementatie van de volgende methoden:
LINQ naar SQL ondersteunt gelijkheid en vergelijking voor platte argumenten, maar niet voor argumenten die reeksen zijn of bevatten. Een plat argument is een type dat kan worden toegewezen aan een SQL-rij. Een projectie van een of meer entiteitstypen die statisch kunnen worden bepaald om geen reeks te bevatten, wordt beschouwd als een plat argument.
Hier volgen enkele voorbeelden van platte argumenten:
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})
Hier volgen enkele voorbeelden van niet-platte (hiërarchische) argumenten:
// 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)
Visual Basic Function Translation
De volgende helperfuncties die door de Visual Basic-compiler worden gebruikt, worden vertaald naar bijbehorende SQL-operators en -functies:
CompareStringDateTime.CompareDecimal.CompareIIf (in Microsoft.VisualBasic.Interaction)
Conversiemethoden:
ToBooleanToSByteToByteToCharToCharArrayRankOneToDateToDecimalToDoubleToIntegerToUIntegerToLongToULongToShortToUShortToSingleToString
Overnameondersteuning
Beperkingen voor erfenismapping
Zie Handleiding: Erfenishierarchieën toewijzen voor meer informatie.
Overname in query's
C#-casts worden alleen ondersteund in projecties. Casts die elders worden gebruikt, worden niet vertaald en genegeerd. Afgezien van sql-functienamen, voert SQL alleen het equivalent van de Common Language Runtime (CLR) Convertuit. Dat wil gezegd, SQL kan de waarde van het ene type wijzigen in een ander type. Er is geen equivalent van CLR cast omdat er geen concept is van het opnieuw interpreteren van dezelfde bits als die van een ander type. Daarom werkt een C#-cast alleen lokaal. Het is niet op afstand bestuurd.
De operators is en , en asde GetType methode zijn niet beperkt tot de Select operator. Ze kunnen ook worden gebruikt in andere queryoperators.
Ondersteuning voor SQL Server 2008
Vanaf .NET Framework 3.5 SP1 ondersteunt LINQ naar SQL toewijzing aan nieuwe datum- en tijdtypen die zijn geïntroduceerd met SQL Server 2008. Er zijn echter enkele beperkingen voor de LINQ voor SQL-queryoperators die u kunt gebruiken wanneer u werkt op basis van waarden die zijn toegewezen aan deze nieuwe typen.
Niet-ondersteunde Query-operators
De volgende queryoperators worden niet ondersteund op waarden die zijn toegewezen aan de nieuwe sql Server-datum- en tijdtypen: DATETIME2, DATE, TIMEen DATETIMEOFFSET.
AggregateAverageLastOrDefaultOfTypeSum
Zie SQL-CLR typetoewijzing voor meer informatie over het toewijzen aan deze SQL Server-datum- en tijdtypen.
Ondersteuning voor SQL Server 2005
LINQ naar SQL biedt geen ondersteuning voor de volgende SQL Server 2005-functies:
Opgeslagen procedures die zijn geschreven voor SQL CLR.
Door de gebruiker gedefinieerd type.
XML-queryfuncties.
Ondersteuning voor SQL Server 2000
De volgende beperkingen van SQL Server 2000 (vergeleken met Microsoft SQL Server 2005) zijn van invloed op LINQ naar SQL-ondersteuning.
Operators voor Cross Apply en Outer Apply
Deze operators zijn niet beschikbaar in SQL Server 2000. LINQ naar SQL probeert een reeks herschrijvingen uit te voeren om ze te vervangen door passende join-operaties.
Cross Apply en Outer Apply worden gegenereerd voor relatienavigatie. De set query's waarvoor dergelijke herschrijven mogelijk zijn, is niet goed gedefinieerd. Daarom is de minimale set query's die worden ondersteund voor SQL Server 2000, de set die geen relatienavigatie omvat.
tekst/ntekst
Gegevenstypen text / ntext kunnen niet worden gebruikt in bepaalde querybewerkingen tegen varchar(max) / nvarchar(max), die worden ondersteund door Microsoft SQL Server 2005.
Er is geen oplossing beschikbaar voor deze beperking. U kunt met name geen enkel resultaat gebruiken van Distinct() dat leden bevat die zijn toegewezen aan de kolommen text of ntext.
Gedrag geactiveerd door geneste query's
SQL Server 2000-binder (door SP4) bevat enkele eigenaardigheden die worden geactiveerd door geneste queries. De set SQL-query's waarmee deze idiosyncrasies worden geactiveerd, is niet goed gedefinieerd. Daarom kunt u de set LINQ niet definiëren voor SQL-query's die sql Server-uitzonderingen kunnen veroorzaken.
Operators overslaan en overnemen
Take en Skip bepaalde beperkingen hebben wanneer ze worden gebruikt in query's voor SQL Server 2000. Voor meer informatie, zie de vermelding 'Skip and Take Exceptions in SQL Server 2000' (Uitzonderingen overslaan en maken in SQL Server 2000) in Probleemoplossing.
Object materialisering
Materialisatie maakt CLR-objecten op basis van rijen die worden geretourneerd door een of meer SQL-query's.
De volgende aanroepen worden lokaal uitgevoerd als onderdeel van materialisatie:
Constructeurs
ToStringmethoden in projectiesTypeconversies in projecties
Methoden die de AsEnumerable methode volgen, worden lokaal uitgevoerd. Deze methode veroorzaakt geen onmiddellijke uitvoering.
U kunt een
structals retourtype van een queryresultaat of als lid van het resultaattype gebruiken. Entiteiten moeten klassen zijn. Anonieme typen worden gerealiseerd als klasse-instanties, maar benoemde structs (niet-entiteiten) kunnen worden gebruikt bij projectie.Een lid van het retourtype van een queryresultaat kan van het type IQueryable<T>zijn. Het wordt gematerialiseerd als een lokale verzameling.
De volgende methoden veroorzaken de onmiddellijke materialisatie van de volgorde waarop de methoden worden toegepast: