6

私は次のSQLクエリを使用しています。

SELECT 
a.AppointmentId,
a.Status,
a.Type,
a.Title,
b.Days,
d.Description,
e.FormId
FROM Appointment a (nolock)
LEFT JOIN AppointmentFormula b (nolock)
ON a.AppointmentId = b.AppointmentId and b.RowStatus = 1
JOIN Type d (nolock)
ON a.Type = d.TypeId
LEFT JOIN AppointmentForm e (nolock)
ON e.AppointmentId = a.AppointmentId
WHERE a.RowStatus = 1
AND a.Type = 1
ORDER BY a.Type

LINQでJOINを実現する方法がわかりません。私のすべてのテーブルには外部キーの関係があります。

4

3 に答える 3

29
SELECT A.X, B.Y
FROM A JOIN B ON A.X = B.Y

この linq メソッド呼び出し (Join への) は、上記の Join を生成します。

var query = A.Join
(
  B,
  a => a.x,
  b => b.y,
  (a, b) => new {a.x, b.y} //if you want more columns - add them here.
);

SELECT A.X, B.Y
FROM A LEFT JOIN B ON A.X = B.Y

これらの linq メソッド呼び出し (GroupJoin、SelectMany、DefaultIfEmpty への) は、上記の Left Join を生成します。

var query = A.GroupJoin
(
  B,
  a => a.x,
  b => b.y,
  (a, g) => new {a, g}
).SelectMany
(
  z => z.g.DefaultIfEmpty(),
  (z, b) =>
    new  { x = z.a.x, y = b.y } //if you want more columns - add them here.
);

ここでの重要な概念は、Linq のメソッドがフラット化された行と列の形状ではなく、階層的に形成された結果を生成するということです。

  • Linqは、要素のコレクション(空ではない可能性があります) にGroupBy一致するグループ化キーを使用して、階層に整形された結果を生成します。SQL の句は、集計された値でグループ化キーを生成します。操作するサブコレクションはありません。GroupBy
  • 同様に、LinqGroupJoinは階層的な形状を生成します。つまり、親レコードが子レコードのコレクション(空の場合もあります) に一致します。SQLLEFT JOINは、各子レコードに一致する親レコードを生成するか、他に一致するものがない場合は null 子レコードを生成します。Linq の形状から Sql の形状に到達するには、子レコードのコレクションをSelectMany- で展開し、 を使用して子レコードの空のコレクションを処理する必要がありますDefaultIfEmpty

そして、これが質問でそのSQLをリンクしようとする私の試みです:

var query =
  from a in Appointment
  where a.RowStatus == 1
  where a.Type == 1
  from b in a.AppointmentFormula.Where(af => af.RowStatus == 1).DefaultIfEmpty()
  from d in a.TypeRecord //a has a type column and is related to a table named type, disambiguate the names
  from e in a.AppointmentForm.DefaultIfEmpty()
  order by a.Type
  select new { a.AppointmentId, a.Status, a.Type, a.Title, b.Days, d.Description, e.Form }
于 2009-06-19T04:30:56.953 に答える
5

私はカフから離れていたので、これを少し調整する必要があるかもしれませんが、覚えておくべき重要なことがいくつかあります. リレーションシップが dbml で適切に設定されている場合は、内部結合を暗黙的に実行し、最初のテーブルからデータにアクセスするだけで済みます。また、LINQ の左結合は私たちが期待するほど単純ではなく、それを実現するには DefaultIfEmpty 構文を使用する必要があります。ここでは匿名型を作成しましたが、DTO クラスなどに入れたいと思うかもしれません。また、ヌルの場合に何をしたいのかわかりませんでしたが、?? を使用できます。値が null の場合に変数に与える値を定義する構文。他にご不明な点がありましたらお知らせください...

var query = (from a in context.Appointment
join b in context.AppointmentFormula on a.AppointmentId equals b.AppointmentId into temp
from c in temp.DefaultIfEmpty()
join d in context.AppointmentForm on a.AppointmentID equals e.AppointmentID into temp2
from e in temp2.DefaultIfEmpty()
where a.RowStatus == 1 && c.RowStatus == 1 && a.Type == 1
select new {a.AppointmentId, a.Status, a.Type, a.Title, c.Days ?? 0, a.Type.Description, e.FormID ?? 0}).OrderBy(a.Type);
于 2009-06-18T14:59:33.257 に答える
1

(NOLOCK) ヒントを保持したい場合は、C# の拡張メソッドを使用した便利なソリューションをブログに投稿しました。これは、クエリ内のすべてのテーブルに nolock ヒントを追加することと同じであることに注意してください。

于 2010-06-09T01:40:54.740 に答える