次の方法で共有


Entity SQL と Transact-SQL の違い

この記事では、Entity SQL と Transact-SQL の違いについて説明します。

継承とリレーションシップのサポート

Entity SQL は概念エンティティ スキーマと直接連携し、継承やリレーションシップなどの概念モデル機能をサポートします。

継承を使用する場合、多くの場合、スーパータイプ インスタンスのコレクションからサブタイプのインスタンスを選択すると便利です。 Entity SQL の oftype 演算子 (C# シーケンスの oftype と同様) は、この機能を提供します。

コレクションのサポート

Entity SQL は、コレクションをファースト クラスのエンティティとして扱います。 例えば次が挙げられます。

  • コレクション式は、 from 句で有効です。

  • in サブクエリと exists サブクエリは、コレクションを許可するように一般化されています。

    サブクエリはコレクションの 1 種類です。 e1 in e2 exists(e)は、これらの操作を実行するための Entity SQL コンストラクトです。

  • unionintersectexceptなどの設定操作がコレクションで動作するようになりました。

  • 結合はコレクションに対して実行されます。

式のサポート

Transact-SQL には、サブクエリ (テーブル) と式 (行と列) があります。

コレクションと入れ子になったコレクションをサポートするために、Entity SQL ではすべてが式になります。 Entity SQL は Transact-SQL よりもコンポーザブルであり、すべての式を任意の場所で使用できます。 クエリ式は常に投影型のコレクションになり、コレクション式が許可されている任意の場所で使用できます。 Entity SQL でサポートされていない Transact-SQL 式の詳細については、「 サポートされていない式」を参照してください。

有効なすべての Entity SQL クエリを次に示します。

1+2 *3  
"abc"  
row(1 as a, 2 as b)  
{ 1, 3, 5}
e1 union all e2  
set(e1)  

サブクエリの均一な処理

テーブルに重点を置いている Transact-SQL は、サブクエリのコンテキスト解釈を実行します。 たとえば、 from 句のサブクエリは、マルチセット (テーブル) と見なされます。 ただし、 select 句で使用されるのと同じサブクエリはスカラー サブクエリと見なされます。 同様に、 in 演算子の左側で使用されるサブクエリはスカラー サブクエリと見なされますが、右側はマルチセット サブクエリと見なされます。

Entity SQL では、これらの違いはなくなります。 式には、使用されるコンテキストに依存しない統一された解釈があります。 Entity SQL では、すべてのサブクエリがマルチセット サブクエリと見なされます。 サブクエリからスカラー値が必要な場合、Entity SQL はコレクション (この場合はサブクエリ) を操作する anyelement 演算子を提供し、コレクションからシングルトン値を抽出します。

サブクエリの暗黙の強制型変換の回避

サブクエリの均一な処理の関連する副作用は、サブクエリからスカラー値への暗黙的な変換です。 具体的には、Transact-SQL では、(1 つのフィールドを持つ) 行のマルチセットが、フィールドのデータ型であるスカラー値に暗黙的に変換されます。

Entity SQL では、この暗黙の強制型変換をサポートしていません。 Entity SQL には、コレクションからシングルトン値を抽出する ANYELEMENT 演算子と、クエリ式中に行ラッパーが作成されないようにするための select value 句が用意されています。

SELECT VALUE: 暗黙の row ラッパーの回避

Transact-SQL サブクエリの select 句は、句内の項目を囲む行ラッパーを暗黙的に作成します。 これは、スカラーまたはオブジェクトのコレクションを作成できないことを意味します。 Transact-SQL では、1 つのフィールドの rowtype と、同じデータ型のシングルトン値との間の暗黙の強制型変換が許可されています。

Entity SQL には、暗黙的な行の構築をスキップする select value 句が用意されています。 select value句で指定できる項目は 1 つだけです。 このような句を使用する場合、 select 句内の項目を囲む行ラッパーは作成されません。たとえば、 select value aなど、目的の図形のコレクションを生成できます。

Entity SQL には、任意の行を構築するための行コンストラクターも用意されています。 select はプロジェクション内の 1 つ以上の要素を受け取り、フィールドを含むデータ レコードになります。

select a, b, c

左相関とエイリアシング

Transact-SQL では、特定のスコープ内の式 ( selectfromなどの 1 つの句) は、同じスコープで前に定義された式を参照できません。 SQL の一部の方言 (Transact-SQLを含む) では、 from 句でこれらの限定的な形式がサポートされています。

Entity SQL は、 from 句の左の相関関係を一般化し、それらを均一に扱います。 from句の式は、構文を追加しなくても、同じ句内の以前の定義 (左側の定義) を参照できます。

Entity SQL では、 group by 句に関連するクエリにも追加の制限が適用されます。 このようなクエリの select 句と having 句の式は、エイリアスを介してのみ group by キーを参照できます。 次のコンストラクトは、Transact-SQL では有効ですが、Entity SQL には含まれません。

SELECT t.x + t.y FROM T AS t group BY t.x + t.y

Entity SQL でこれを行うには:

SELECT k FROM T AS t GROUP BY (t.x + t.y) AS k

テーブル (コレクション) の列 (プロパティ) の参照

Entity SQL のすべての列参照は、テーブルの別名で修飾する必要があります。 次のコンストラクト ( a がテーブル Tの有効な列であると想定) は、Transact-SQL では有効ですが、Entity SQL では有効ではありません。

SELECT a FROM T

Entity SQL フォームは次のとおりです。

SELECT t.a AS A FROM T AS t

テーブルのエイリアスは、 from 句では省略可能です。 テーブルの名前は、暗黙的なエイリアスとして使用されます。 Entity SQL では、次の形式も使用できます。

SELECT Tab.a FROM Tab

Transact-SQL では、テーブルの (行) の列を参照するために "." 表記が使用されます。 Entity SQL は、この表記を (プログラミング言語から借用して) 拡張して、オブジェクトのプロパティを介したナビゲーションをサポートします。

たとえば、 p が Person 型の式である場合、このユーザーの住所の市区町村を参照するための Entity SQL 構文を次に示します。

p.Address.City

* のサポートなし

Transact-SQL では、非修飾の * 構文が行全体の別名としてサポートされ、修飾された * 構文 (t.*) がそのテーブルのフィールドのショートカットとしてサポートされます。 さらに、Transact-SQL では、null を含む特殊な count(*) 集計を使用できます。

Entity SQL では、 * コンストラクトはサポートされていません。 フォーム select * from Tselect T1.* from T1, T2... の Transact-SQL クエリは、それぞれ select value t from T as t および select value t1 from T1 as t1, T2 as t2... として Entity SQL で表すことができます。 さらに、これらのコンストラクトは継承 (値の置換可能性) を処理しますが、 select * バリアントは宣言された型の最上位のプロパティに制限されます。

Entity SQL では、 count(*) 集計はサポートされていません。 count(0) を代わりに使用します。

Group By への変更

Entity SQL では、 group by キーのエイリアス化がサポートされています。 select句と having 句の式は、これらのエイリアスを介してgroup by キーを参照する必要があります。 たとえば、次の Entity SQL 構文です。

SELECT k1, count(t.a), sum(t.a)
FROM T AS t
GROUP BY t.b + t.c AS k1

...は、次の Transact-SQL と同じです。

SELECT b + c, count(*), sum(a)
FROM T
GROUP BY b + c

コレクションベースの集計

Entity SQL では、2 種類の集計がサポートされています。

コレクションベースの集計はコレクションに対して動作し、集計結果を生成します。 これらはクエリ内の任意の場所に表示でき、 group by 句は必要ありません。 例えば次が挙げられます。

SELECT t.a AS a, count({1,2,3}) AS b FROM T AS t

Entity SQL では、SQL スタイルの集計もサポートされています。 例えば次が挙げられます。

SELECT a, sum(t.b) FROM T AS t GROUP BY t.a AS a

ORDER BY 句の使用方法

Transact-SQL では、 ORDER BY 句を最上位の SELECT .. FROM .. WHERE ブロックでのみ指定できます。 Entity SQL では、入れ子になった ORDER BY 式を使用でき、クエリ内の任意の場所に配置できますが、入れ子になったクエリでの順序付けは保持されません。

-- The following query will order the results by the last name  
SELECT C1.FirstName, C1.LastName  
        FROM AdventureWorks.Contact AS C1
        ORDER BY C1.LastName  
-- In the following query ordering of the nested query is ignored.  
SELECT C2.FirstName, C2.LastName  
    FROM (SELECT C1.FirstName, C1.LastName  
        FROM AdventureWorks.Contact as C1  
        ORDER BY C1.LastName) as C2  

識別子

Transact-SQL では、識別子の比較は現在のデータベースの照合順序に基づいています。 Entity SQL の識別子では、常に大文字と小文字は区別されず、アクセントは区別されます (つまり、Entity SQL ではアクセントのある文字とアクセントのない文字が区別されます。たとえば、'a' と 'ấ' は等しくありません)。 Entity SQL は、同じように表示されるが、異なるコード ページからの文字のバージョンを異なる文字として扱います。 詳細については、「 入力文字セット」を参照してください。

エンティティ SQL で使用できない Transact-SQL 機能

Entity SQL では、次の Transact-SQL 機能を使用できません。

DML (データ管理言語)
Entity SQL では現在、DML ステートメント (挿入、更新、削除) はサポートされていません。

データ定義言語 (DDL)
Entity SQL では、現在のバージョンの DDL はサポートされません。

命令型プログラミング
Entity SQL では、Transact-SQL とは異なり、命令型プログラミングはサポートされません。 代わりにプログラミング言語を使用してください。

グループ化関数
Entity SQL では、グループ化関数 (CUBE、ROLLUP、GROUPING_SETなど) はまだサポートされていません。

分析関数
Entity SQL では、分析関数はサポートされていません (まだ)。

組み込み関数、演算子
Entity SQL では、Transact-SQL の組み込み関数と演算子のサブセットがサポートされています。 これらの演算子と関数は、主要なストア プロバイダーによってサポートされる可能性があります。 Entity SQL では、プロバイダー マニフェストで宣言されたストア固有の関数が使用されます。 さらに、Entity Framework では、Entity SQL で使用する組み込みストア関数とユーザー定義の既存のストア関数を宣言できます。

[ヒント]
Entity SQL には、クエリ ヒントのメカニズムは用意されていません。

クエリ結果のバッチ処理
Entity SQL では、クエリ結果のバッチ処理はサポートされていません。 たとえば、有効な Transact-SQL (バッチとして送信) は次のとおりです。

SELECT * FROM products;
SELECT * FROM categories;

ただし、同等の Entity SQL はサポートされていません。

SELECT value p FROM Products AS p;
SELECT value c FROM Categories AS c;

Entity SQL では、コマンドごとに 1 つの結果生成クエリ ステートメントのみがサポートされます。

こちらも参照ください