1


1

LINQtoSQLが生成したSQLの外部結合が多すぎます

LINQ2SQLクエリによって生成されたSQLステートメントについて質問があります。 私は2つのデータベーステーブルを持っています( `VisibleForDepartmentId`は外部キーです):

AssignableObject                 Department
----------------------           ------------
AssignableObjectId        ┌────> DepartmentId
AssignableObjectType      │
VisibleForDepartmentId ───┘

そして、以下のマッピング情報( `AssignableObject`は抽象的です)に注意してください。


そして、次のコード:

var loadOptions = new DataLoadOptions();
loadOptions.LoadWith(a => a.VisibleForDepartment);
dataContext.LoadOptions = loadOptions;
var assets = from a in dataContext.Assets
             select a;

これにより、2つの同一の左外部結合を含むSQLクエリが生成されます。

SELECT t0.AssignableObjectType, t0.AssignableObjectId, t0.VisibleForDepartmentId,
       t2.test, t2.DepartmentId, t2.Name, t4.test AS test2,
       t4.DepartmentId AS DepartmentId2, t4.Name AS Name2
FROM dbo.AssignableObject AS t0
LEFT OUTER JOIN (
    SELECT 1 AS test, t1.DepartmentId, t1.Name
    FROM dbo.Department AS t1
    ) AS t2 ON t2.DepartmentId = t0.VisibleForDepartmentId
LEFT OUTER JOIN (
    SELECT 1 AS test, t3.DepartmentId, t3.Name
    FROM dbo.Department AS t3
    ) AS t4 ON t4.DepartmentId = t0.VisibleForDepartmentId

一方では十分だったはずの外部結合が2つあるのはなぜですか。

敬具、

ロナルド

4 回答


3


私はこれらの重複した外部結合の原因を見つけました。 永続クラスが2つ以上のサブクラスによって継承されると発生します。 `LoadWith`を使うと、それぞれのサブクラスに対して新しい外部結合が生成されたSQL文に追加されます。

私の例では、 AssignableObject`は Asset`と `Role`の2つのサブクラスを持っています。 これは `Department`テーブルと2つの外部結合をもたらします。 別のサブクラスを追加すると、3番目の外部結合が追加されます。

SQL Serverが、外部結合が重複していることを認識するのに十分スマートかどうかはわかりません。 Microsoft Connectでhttps://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=434254 [これを投稿しました]。

編集:どうやら私の問題はhttps://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=361683 [その他の問題]の複製であり、LINQ2SQLの次のリリースで修正される予定はありません。


1


データベース上で同じ2つのテーブルの同じ2つの列の間に誤って2つの外部キー関係が定義されていますか。


0


クエリ自体の中で左外部結合を試すことができます。 データベースがないため、どのSQLが生成されるのかわかりません。

a .VisibleForDepartmentId上のdataContext.Departments内のvar assets = from aは、dからdataContext.Departmentsに結合します。


0


デフォルトのデータベースを使用してLINQPadで同様のクエリを作成しました。

var loadOptions = new DataLoadOptions(); loadOptions.LoadWith(a => a.Category); LoadOptions = loadOptions;

var products = Productsのaからaを選択します。

products.Dump();

そして得る

SELECT [t0]。[ProductID]、[t0]。[ProductName]、[t0]。[CategoryID]、[t2]。[test]、[t2]。[CategoryID] AS [CategoryID2]、[t2]。[ [商品名]から[商品名] AS [t0]左外部結合(SELECT 1 AS [テスト]、[t1]。[カテゴリID]、[t1]。[カテゴリ名] FROM [カテゴリ] AS [t1])AS [t2] ON [t2]。[CategoryID] = [t0]。[CategoryID]

期待通りに1つのOUTER JOINのみが使用されます。