Standard lekérdezési operátor fordítása
A LINQ és az SQL a standard lekérdezési operátorokat SQL-parancsokra fordítja. Az adatbázis lekérdezésfeldolgozója határozza meg az SQL-fordítás végrehajtási szemantikáját.
A standard lekérdezési operátorok szekvenciák alapján vannak definiálva. A szekvencia rendezve van, és a sorozat minden eleméhez referencia-identitásra támaszkodik. További információ: Standard lekérdezési operátorok áttekintése (C#) vagy Standard lekérdezési operátorok áttekintése (Visual Basic).
Az SQL elsősorban rendezetlen értékkészletekkel foglalkozik. A rendezés általában egy explicit módon megadott, utófeldolgozási művelet, amelyet a rendszer a lekérdezés végső eredményére alkalmaz, nem pedig a köztes eredményekre. Az identitást értékek határozzák meg. Ezért az SQL-lekérdezések a készletek helyett a többhalmazos (zsákos) kezelésre vannak értelmezve.
A következő bekezdések a standard lekérdezési operátorok és az SQL Server-szolgáltató sql-fordítása közötti különbségeket írják le a LINQ-ról SQL-re.
Operátor támogatása
Concat
A Concat metódus olyan rendezett többhalmazokhoz van definiálva, ahol a fogadó sorrendje és az argumentum sorrendje megegyezik. ConcatUNION ALL
a többhalmazos, majd a közös sorrend által követett módon működik.
Az utolsó lépés az SQL-ben történő rendezés az eredmények létrehozása előtt. Concat argumentumainak sorrendjét nem őrzi meg. A megfelelő sorrend biztosítása érdekében kifejezetten meg kell rendelnie a következő eredményeit Concat: .
Metszet, kivéve, unió
A Intersect metódusok és Except a metódusok csak a készleteken vannak jól definiálva. A többhalmazos szemantika nincs meghatározva.
A Union metódus többhalmaz esetében a többhalmazok rendezetlen összefűzéseként van definiálva (gyakorlatilag az SQL UNION ALL záradékának eredménye).
Take, Skip
Takeés Skip a metódusok csak rendezett csoportokhoz vannak jól definiálva. A rendezetlen csoportok vagy többhalmazok szemantikája nincs meghatározva.
Feljegyzés
Take és Skip bizonyos korlátozások vonatkoznak rájuk, amikor az SQL Server 2000-hez tartozó lekérdezésekben használják őket. További információ: "Kihagyás és kivételezés az SQL Server 2000-ben" bejegyzés a Hibaelhárításban.
Az SQL-ben való rendezés korlátozásai miatt a LINQ az SQL-hez megpróbálja áthelyezni a metódus argumentumának sorrendjét a metódus eredményére. Vegyük például a következő LINQ-t az SQL-lekérdezéshez:
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
A kódhoz létrehozott SQL az alábbiak szerint helyezi át a sorrendet a végére:
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]
Nyilvánvalóvá válik, hogy az összes megadott sorrendnek konzisztensnek kell lennie, amikor Take és Skip amelyek össze vannak kötve. Ellenkező esetben az eredmények nincs meghatározva.
Skip Mindkettő Take jól definiálva van a standard lekérdezési operátor specifikációja alapján nem negatív, állandó integrál argumentumokhoz.
Fordítás nélküli operátorok
A LINQ nem fordítja le az alábbi metódusokat az SQL-hez. A leggyakoribb ok a rendezetlen többhalmazok és a sorozatok közötti különbség.
Operátorok | Logika |
---|---|
TakeWhile, SkipWhile | Az SQL-lekérdezések többhalmazon működnek, nem sorozatokon. ORDER BY az eredményekre alkalmazott utolsó záradéknak kell lennie. Ezért e két módszerhez nincs általános célú fordítás. |
Reverse | Ennek a módszernek a fordítása egy rendezett készlet esetében lehetséges, de jelenleg nem fordítja le a LINQ az SQL-be. |
Last, LastOrDefault | Ezeknek a módszereknek a fordítása egy rendezett készlet esetében lehetséges, de jelenleg nem fordítja le a LINQ az SQL-hez. |
ElementAt, ElementAtOrDefault | Az SQL-lekérdezések többhalmazon működnek, nem indexelhető sorozatokon. |
DefaultIfEmpty (túlterhelés az alapértelmezett arg-vel) | Általában nem adható meg alapértelmezett érték tetszőleges rekordhoz. A tuplok null értékei bizonyos esetekben külső illesztéseken keresztül is lehetségesek. |
Kifejezésfordítás
Null szemantika
Az SQL-hez való LINQ nem ír elő null összehasonlító szemantikát az SQL-hez. Az összehasonlító operátorok szintaktikailag le vannak fordítva az SQL-ekvivalensekre. Ezért a szemantikák a kiszolgáló- vagy kapcsolatbeállítások által definiált SQL-szemantikát tükrözik. Két null érték például egyenlőtlennek minősül az alapértelmezett SQL Server-beállítások között, de a szemantikát módosíthatja a beállításokon. A LINQ–SQL nem veszi figyelembe a kiszolgáló beállításait a lekérdezések lefordításakor.
A literális nullértékkel való összehasonlítás a megfelelő SQL-verzióra (is null
vagy is not null
) lesz lefordítva.
A rendezés értékét null
az SQL Server határozza meg. A LINQ és az SQL nem módosítja a rendezést.
Összesítések
A Standard lekérdezési operátor aggregátum metódusa Sum nullára értékel egy üres sorozatot vagy egy csak null értéket tartalmazó sorozatot. A LINQ-ban az SQL szemantikája változatlan marad, és Sum nulla helyett egy üres sorozatra vagy egy csak null értéket tartalmazó sorozatra értékeli null
ki.
A köztes eredményekRE vonatkozó SQL-korlátozások a LINQ-ban lévő összesítésekre vonatkoznak az SQL-ben. A Sum 32 bites egész számok mennyisége nem számítható ki 64 bites eredmények használatával. A LINQ-ból SQL-fordításba Sumtörténő túlcsordulás akkor is előfordulhat, ha a Standard lekérdezési operátor implementációja nem okoz túlcsordulást a megfelelő memóriabeli sorozathoz.
Hasonlóképpen, az egész számértékek LINQ-ról Average SQL-fordítására nem integer
double
.
Entitásargumentumok
A LINQ–SQL lehetővé teszi az entitástípusok használatát a GroupBy metódusokban.OrderBy Ezen operátorok fordítása során egy típus argumentumának használata egyenértékűnek tekinthető az adott típus összes tagjának megadásával. A következő kód például egyenértékű:
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})
Egyenértékű/összehasonlítható argumentumok
Az alábbi módszerek végrehajtásához argumentumok egyenlőségére van szükség:
Az SQL-hez készült LINQ támogatja az egyenlőséget és az összehasonlítást az egyenrangú argumentumok esetében, a sorozatokat tartalmazó vagy tartalmazó argumentumok esetében azonban nem. Az egybesimított argumentum egy SQL-sorra leképezhető típus. Egy vagy több olyan entitástípus kivetítése, amely statikusan meghatározható, hogy nem tartalmaz sorozatot, egybesimított argumentumnak minősül.
Az alábbi példák egybesimított argumentumokra mutatnak be példákat:
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})
Az alábbi példák nem egysíkú (hierarchikus) argumentumokra mutatnak be példákat:
// 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 Függvény fordítása
A Visual Basic fordító által használt alábbi segédfüggvények a megfelelő SQL-operátorok és -függvények számára lesznek lefordítva:
CompareString
DateTime.Compare
Decimal.Compare
IIf (in Microsoft.VisualBasic.Interaction)
Konverziós módszerek:
ToBoolean
ToSByte
ToByte
ToChar
ToCharArrayRankOne
ToDate
ToDecimal
ToDouble
ToInteger
ToUInteger
ToLong
ToULong
ToShort
ToUShort
ToSingle
ToString
Öröklés támogatása
Öröklés-leképezési korlátozások
További információ : Öröklési hierarchiák leképezése.
Öröklés lekérdezésekben
A C#-vetítések csak a vetítésben támogatottak. A máshol használt öntvények nem lesznek lefordítva, és figyelmen kívül hagyják. Az SQL-függvényneveken kívül az SQL valóban csak a közös nyelvi futtatókörnyezet (CLR) Convertmegfelelőjét hajtja végre. Vagyis az SQL módosíthatja az egyik típus értékét egy másikra. A CLR-vetítésnek nincs megfelelője, mert nem létezik olyan fogalom, amely ugyanazt a bitet értelmezi újra, mint egy másik típusé. Ezért csak helyileg működik a C#-szereplők. Nincs távolról.
Az operátorok és is
as
a GetType
metódus nem korlátozódik az Select
operátorra. Más lekérdezési operátorokban is használhatók.
AZ SQL Server 2008 támogatása
A .NET-keretrendszer 3.5 SP1-től kezdve a LINQ to SQL támogatja az SQL Server 2008-ban bevezetett új dátum- és időtípusokra való leképezést. Az SQL-lekérdezési operátorokra vonatkozó LINQ-korlátozás azonban bizonyos korlátozásokat tartalmaz, amelyeket akkor használhat, ha az ilyen típusú értékeken működik.
Nem támogatott lekérdezési operátorok
A következő lekérdezési operátorok nem támogatottak az új SQL Server dátum- és időtípusához rendelt értékeken: DATETIME2
, DATE
, TIME
és DATETIMEOFFSET
.
Aggregate
Average
LastOrDefault
OfType
Sum
Az SQL Server dátum- és időtípusainak leképezéséről további információt az SQL-CLR típusleképezés című témakörben talál.
AZ SQL Server 2005 támogatása
A LINQ–SQL nem támogatja a következő SQL Server 2005-funkciókat:
Az SQL CLR-hez írt tárolt eljárások.
Felhasználó által definiált típus.
XML-lekérdezési funkciók.
SQL Server 2000-támogatás
Az SQL Server 2000 alábbi korlátozásai (a Microsoft SQL Server 2005-höz képest) hatással vannak a LINQ-ra az SQL-támogatásra.
Kereszten alkalmazott és külső alkalmazású operátorok
Ezek az operátorok nem érhetők el az SQL Server 2000-ben. A LINQ-ről SQL-re való átírások sorozatát próbálja megfelelő illesztésekre cserélni.
Cross Apply
és Outer Apply
kapcsolatnavigációkhoz jönnek létre. Azoknak a lekérdezéseknek a készlete, amelyekhez ilyen átírások lehetségesek, nem definiálható megfelelően. Ezért az SQL Server 2000-ben támogatott lekérdezések minimális készlete az a készlet, amely nem jár kapcsolatnavigációval.
szöveg / ntext
Bizonyos lekérdezési műveletekbennvarchar(max)
/ varchar(max)
nem használhatók adattípusoktext
/ ntext
, amelyeket a Microsoft SQL Server 2005 támogat.
Erre a korlátozásra nem áll rendelkezésre megoldás. Konkrétan nem használhat Distinct()
olyan eredményt, amely a tagokra vagy oszlopokra van megfeleltetve text
ntext
.
Beágyazott lekérdezések által aktivált viselkedés
Az SQL Server 2000 (SP4-en keresztüli) iratgyűjtő rendelkezik néhány idioszinkrással, amelyeket beágyazott lekérdezések aktiválnak. Az idioszinkronizálásokat kiváltó SQL-lekérdezések készlete nincs megfelelően definiálva. Ezért nem határozhatja meg a LINQ és az SQL-lekérdezések halmazát, amelyek SQL Server-kivételeket okozhatnak.
Operátorok kihagyása és átvétele
Take és Skip bizonyos korlátozások vonatkoznak rájuk, amikor az SQL Server 2000-hez tartozó lekérdezésekben használják őket. További információ: "Kihagyás és kivételezés az SQL Server 2000-ben" bejegyzés a Hibaelhárításban.
Objektum materializálása
A materializálás CLR-objektumokat hoz létre egy vagy több SQL-lekérdezés által visszaadott sorokból.
A következő hívásokat helyileg hajtja végre a materializálás részeként:
Konstruktorok
ToString
vetületi módszerekVetítések típusjelei
A metódust AsEnumerable követő metódusok helyileg lesznek végrehajtva. Ez a módszer nem okoz azonnali végrehajtást.
A lekérdezés eredményének visszatérési típusaként vagy az eredménytípus tagjaként is használható
struct
. Az entitásoknak osztályoknak kell lenniük. A névtelen típusok osztálypéldányként vannak materializálva, de a nevesített szerkezetek (nem entitások) használhatók a kivetítésben.A lekérdezési eredmény visszatérési típusának tagja lehet típus IQueryable<T>. Helyi gyűjteményként van materializálva.
A következő metódusok a metódusok által alkalmazott sorozat azonnali materializálását okozzák: