Sdílet prostřednictvím


Převod standardních operátorů dotazů

LINQ to SQL překládá standardní operátory dotazů na příkazy SQL. Procesor dotazů databáze určuje sémantiku provádění překladu SQL.

Standardní operátory dotazů jsou definovány proti sekvencí. Sekvence je seřazená a spoléhá na referenční identitu pro každý prvek sekvence. Další informace najdete v tématu Přehled operátorů standardních dotazů (C#) nebo Přehled operátorů standardních dotazů (Visual Basic).

SQL se zabývá primárně neuspořádanými sadami hodnot. Řazení je obvykle explicitně uvedená operace následného zpracování, která se použije na konečný výsledek dotazu, nikoli na přechodné výsledky. Identita je definována hodnotami. Z tohoto důvodu jsou dotazy SQL srozumitelné pro práci s více sadami (taškami) místo sad.

Následující odstavce popisují rozdíly mezi standardními operátory dotazů a jejich překladem SQL pro zprostředkovatele SQL Serveru pro LINQ to SQL.

Podpora operátorů

Concat

Metoda Concat je definována pro uspořádané více sad, kde pořadí příjemce a pořadí argumentu jsou stejné. Concat funguje stejně jako UNION ALL u více sad následovaných společným pořadím.

Posledním krokem je řazení v SQL před vytvořením výsledků. Concat nezachová pořadí argumentů. Chcete-li zajistit odpovídající řazení, je nutné explicitně uspořádat výsledky Concat.

Protíná, s výjimkou, Sjednocení

Tyto Intersect metody Except jsou dobře definované pouze u sad. Sémantika více sad není definována.

Metoda Union je definována pro více sad jako neuspořádané zřetězení více sad (účinně výsledek klauzule UNION ALL v SQL).

Vezměte, přeskočte

Take a Skip metody jsou dobře definované pouze pro seřazené sady. Sémantika pro neuspořádané sady nebo více sad není definována.

Poznámka:

Take a Skip mají určitá omezení, pokud se používají v dotazech na SQL Server 2000. Další informace naleznete v části Přeskočit a přijmout výjimky v SQL Serveru 2000 v řešení potíží.

Kvůli omezením řazení v SQL se LINQ to SQL pokusí přesunout pořadí argumentů těchto metod na výsledek metody. Představte si například následující dotaz LINQ to SQL:

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

Vygenerovaný kód SQL pro tento kód přesune pořadí na konec následujícím způsobem:

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]

Je zřejmé, že všechna zadaná řazení musí být konzistentní, když Take jsou Skip zřetězený dohromady. V opačném případě jsou výsledky nedefinované.

Obě Take a Skip jsou dobře definované pro nezáporné konstantní celočíselné argumenty založené na specifikaci standardního operátoru dotazu.

Operátory bez překladu

LinQ to SQL nepřekládá následující metody. Nejběžnějším důvodem je rozdíl mezi neuspořádanými vícemnožinami a sekvencemi.

Operátory Odůvodnění
TakeWhile, SkipWhile Dotazy SQL pracují s více sadami, ne na sekvencích. ORDER BY musí být poslední klauzule použitá na výsledky. Z tohoto důvodu neexistuje pro tyto dvě metody žádný překlad pro obecné účely.
Reverse Překlad této metody je možné pro seřazenou sadu, ale v současné době není přeložen jazykem LINQ do SQL.
Last, LastOrDefault Překladtěchtoch metod je možné pro seřazenou sadu, ale není v současné době přeložen jazykem LINQ do SQL.
ElementAt, ElementAtOrDefault Dotazy SQL pracují s více sadami, ne s indexovatelnými sekvencemi.
DefaultIfEmpty (přetížení s výchozí arg) Obecně platí, že výchozí hodnotu nelze zadat pro libovolnou řazenou kolekci členů. Hodnoty null pro řazené kolekce členů jsou v některých případech možné prostřednictvím vnějších spojení.

Překlad výrazů

Sémantika Null

LINQ to SQL neukládá sémantiku porovnání null pro SQL. Relační operátory se syntakticky překládají na jejich ekvivalenty SQL. Z tohoto důvodu sémantika odráží sémantiku SQL definovanou nastavením serveru nebo připojení. Například dvě hodnoty null jsou považovány za nerovné v rámci výchozího nastavení SQL Serveru, ale můžete změnit nastavení pro změnu sémantiky. LINQ to SQL při překladu dotazů nebere v úvahu nastavení serveru.

Porovnání s hodnotou null literálu se přeloží na příslušnou verzi SQL (is null nebo is not null).

Hodnota null kolace je definována SQL Serverem. LINQ to SQL nemění kolaci.

Souhrny

Agregační metoda Sum Operátor standardního dotazu se vyhodnotí jako nula pro prázdnou sekvenci nebo pro sekvenci, která obsahuje pouze hodnoty null. V LINQ to SQL se sémantika SQL nezmění a Sum vyhodnotí se null místo nuly pro prázdnou sekvenci nebo pro sekvenci, která obsahuje pouze hodnoty null.

Omezení SQL u průběžných výsledků platí pro agregace v LINQ to SQL. Sum 32bitové celočíselné množství se nevypočítá pomocí 64bitových výsledků. K přetečení může dojít u překladu SumLINQ to SQL , i když implementace standardního operátoru dotazu nezpůsobí přetečení odpovídající sekvence v paměti.

Podobně se překlad LINQ to SQL Average celočíselných hodnot vypočítá jako , integerne jako double.

Argumenty entity

LINQ to SQL umožňuje použití typů entit v metodách GroupBy a OrderBy metodách. Při překladu těchto operátorů je použití argumentu typu považováno za ekvivalent pro určení všech členů tohoto typu. Například následující kód je ekvivalentní:

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})

Rovníkové / srovnatelné argumenty

Při implementaci následujících metod je vyžadována rovnost argumentů:

LINQ to SQL podporuje rovnost a porovnání pro ploché argumenty, ale ne pro argumenty, které jsou nebo obsahují sekvence. Plochý argument je typ, který lze mapovat na řádek SQL. Projekce jednoho nebo více typů entit, které lze staticky určit, že neobsahují sekvenci, se považuje za plochý argument.

Tady jsou příklady plochých argumentů:

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})

Tady jsou příklady nerovných (hierarchických) argumentů:

// 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)

Překlad funkcí jazyka Visual Basic

Následující pomocné funkce používané kompilátorem jazyka Visual Basic jsou přeloženy do odpovídajících operátorů a funkcí SQL:

  • CompareString

  • DateTime.Compare

  • Decimal.Compare

  • IIf (in Microsoft.VisualBasic.Interaction)

Metody převodu:

  • ToBoolean
  • ToSByte
  • ToByte
  • ToChar
  • ToCharArrayRankOne
  • ToDate
  • ToDecimal
  • ToDouble
  • ToInteger
  • ToUInteger
  • ToLong
  • ToULong
  • ToShort
  • ToUShort
  • ToSingle
  • ToString

Podpora dědičnosti

Omezení mapování dědičnosti

Další informace naleznete v tématu Postupy: Mapování hierarchií dědičnosti.

Dědičnost v dotazech

Přetypování jazyka C# se podporuje pouze v projekci. Přetypování, která se používají jinde, se nepřeloží a ignorují se. Kromě názvů funkcí SQL provádí SQL pouze ekvivalent modulu CLR (Common Language Runtime). Convert To znamená, že SQL může změnit hodnotu jednoho typu na jiný. Neexistuje žádný ekvivalent přetypování CLR, protože neexistuje žádný koncept reinterpretace stejných bitů jako ty z jiného typu. Proto přetypování jazyka C# funguje jenom místně. Není vzdálený.

Operátory is a asa GetType metoda nejsou omezeny na Select operátor. Dají se použít také v jiných operátorech dotazů.

Podpora SQL Serveru 2008

Počínaje rozhraním .NET Framework 3.5 SP1 podporuje LINQ to SQL mapování na nové typy data a času zavedené s SQL Serverem 2008. Existují ale určitá omezení pro operátory dotazů LINQ to SQL, které můžete použít při použití s hodnotami namapovanými na tyto nové typy.

Nepodporované operátory dotazů

Následující operátory dotazu nejsou podporovány u hodnot mapovaných na nové typy data a času SQL Serveru: DATETIME2, DATE, TIMEa DATETIMEOFFSET.

  • Aggregate

  • Average

  • LastOrDefault

  • OfType

  • Sum

Další informace o mapování na tyto typy data a času SQL Serveru naleznete v tématu MAPOVÁNÍ typů SQL-CLR.

Podpora SQL Serveru 2005

LINQ to SQL nepodporuje následující funkce SYSTÉMU SQL Server 2005:

  • Uložené procedury napsané pro SQL CLR

  • Uživatelem definovaný typ.

  • Funkce dotazu XML.

Podpora SQL Serveru 2000

Následující omezení SYSTÉMU SQL Server 2000 (ve srovnání s Microsoft SQL Serverem 2005) ovlivňují podporu LINQ to SQL.

Křížové použití a vnější operátory použití

Tyto operátory nejsou v SYSTÉMU SQL Server 2000 k dispozici. LINQ to SQL se pokusí řadu přepisů nahradit odpovídajícími spojeními.

Cross Apply a Outer Apply jsou generovány pro navigace relací. Sada dotazů, pro které jsou takové přepisy možné, není dobře definovaná. Z tohoto důvodu je minimální sada dotazů podporovaných pro SQL Server 2000 sada, která nezahrnuje navigaci relací.

text / ntext

Datové typy text / ntext nelze použít v určitých operacích varchar(max) / nvarchar(max)dotazů, které jsou podporovány microsoft SQL Serverem 2005.

Pro toto omezení není k dispozici žádné řešení. Konkrétně nelze použít Distinct() žádný výsledek, který obsahuje členy mapované na text sloupce nebo ntext sloupce.

Chování aktivované vnořenými dotazy

Pořadač SQL Serveru 2000 (až SP4) obsahuje některé idiosyncrasy, které se aktivují vnořenými dotazy. Sada dotazů SQL, které tyto idiosyncrasy aktivují, není dobře definovaná. Z tohoto důvodu nelze definovat sadu dotazů LINQ to SQL, které by mohly způsobit výjimky SQL Serveru.

Přeskočení a převzetí operátorů

Take a Skip mají určitá omezení, pokud se používají v dotazech na SQL Server 2000. Další informace naleznete v části Přeskočit a přijmout výjimky v SQL Serveru 2000 v řešení potíží.

Materializace objektů

Materializace vytváří objekty CLR z řádků vrácených jedním nebo více dotazy SQL.

  • Následující volání se spouští místně jako součást materializace:

    • Konstruktory

    • ToString metody v projekcích

    • Přetypování typů v projekcích

  • Metody, které následují za metodou AsEnumerable , se spouští místně. Tato metoda nezpůsobí okamžité spuštění.

  • Můžete použít struct jako návratový typ výsledku dotazu nebo jako člena typu výsledku. Entity musí být třídy. Anonymní typy jsou materializovány jako instance třídy, ale pojmenované struktury (jiné než entity) lze použít v projekci.

  • Člen návratového typu výsledku dotazu může být typu IQueryable<T>. Je materializován jako místní kolekce.

  • Následující metody způsobují okamžitou materializaci sekvence, na kterou se metody použijí:

Viz také