1

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

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

そして、次のマッピング情報 (AssignableObject抽象的であることに注意してください):

<Database Name="SO_755661" Class="DataClassesDataContext">
  <Table Name="dbo.AssignableObject" Member="AssignableObjects">
    <Type Name="AssignableObject" Modifier="Abstract">
      <Column Name="AssignableObjectId" Type="System.Int32"
              DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true"
              IsDbGenerated="true" CanBeNull="false" />
      <Column Name="AssignableObjectType" Type="System.String"
              DbType="VarChar(50) NOT NULL" CanBeNull="false"
              AccessModifier="Private" IsDiscriminator="true"/>
      <Column Name="VisibleForDepartmentId" Type="System.Int32"
              DbType="Int" CanBeNull="true" />
      <Association Name="Department_AssignableObject" Member="VisibleForDepartment"
                   ThisKey="VisibleForDepartmentId" OtherKey="DepartmentId"
                   Type="Department" IsForeignKey="true" />
      <Type Name="Asset" InheritanceCode="Asset" IsInheritanceDefault="true" />
      <Type Name="Role" InheritanceCode="Role" />
    </Type>
  </Table>
  <Table Name="dbo.Department" Member="Departments">
    <Type Name="Department">
      <Column Name="DepartmentId" Type="System.Int32"
              DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true"
              IsDbGenerated="true" CanBeNull="false" />
      <Column Name="Name" Type="System.String" DbType="VarChar(50) NOT NULL"
              CanBeNull="false" />
      <Association Name="Department_AssignableObject" Member="AssignableObjects"
                   ThisKey="DepartmentId" OtherKey="VisibleForDepartmentId"
                   Type="AssignableObject" />
    </Type>
  </Table>
</Database>

そして、次のコード:

var loadOptions = new DataLoadOptions();
loadOptions.LoadWith<Asset>(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

1 つあれば十分な外部結合が 2 つあるのはなぜですか?

敬具、

ロナルド

4

4 に答える 4

3

これらの重複する外部結合の原因を突き止めました。これらは、永続クラスが 2 つ以上のサブクラスによって継承されるときに発生します。を使用すると、サブクラスごとに、生成された SQL ステートメントに新しい外部結合が追加されますLoadWith

私の例でAssignableObjectは、 には と の 2 つのサブクラスがAssetありRoleます。これにより、テーブルとの 2 つの外部結合が発生しDepartmentます。別のサブクラスを追加すると、3 つ目の外部結合が追加されます。

外部結合が重複していることを認識できるほど SQL Server が賢いかどうかはわかりません。これを Microsoft Connect に投稿しました。

編集:どうやら私の問題は別の問題の重複であり、LINQ2SQLの次のリリースでは修正されません。

于 2009-04-22T06:59:41.160 に答える
1

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

于 2009-04-16T11:24:30.023 に答える
0

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

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

var products = from a in Products
               select a;

products.Dump();

そして得る

SELECT [t0].[ProductID], [t0].[ProductName], [t0].[CategoryID], [t2].[test], [t2].[CategoryID] AS [CategoryID2], [t2].[CategoryName]
FROM [Products] AS [t0]
LEFT OUTER JOIN (
    SELECT 1 AS [test], [t1].[CategoryID], [t1].[CategoryName]
    FROM [Categories] AS [t1]
    ) AS [t2] ON [t2].[CategoryID] = [t0].[CategoryID]

期待どおり、1 つの OUTER JOIN のみが使用されます。

于 2009-04-20T06:34:40.113 に答える
0

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

var assets = from a in dataContext.Assets
             join d in dataContext.Departments on 
                  a.VisibleForDepartmentId equals d.DepartmentId
                  into temp
             from t in temp.DefaultIfEmpty()
             select a;
于 2009-04-17T18:00:15.980 に答える