2009-07-07 16 views
5

Linqの左結合については既に多くの質問があります。私が見てきた左結合については、joinキーワードを使用して目的の目的を達成しています。Linqに参加しましたか?

これは私には意味がありません。テーブルCustomerInvoiceがあり、外部キーCustomerIDInvoiceにリンクされているとします。今、顧客情報と請求書を含むレポートを実行したいと思います。 SQLは次のようになります。私はSOに答えを見てきたもの、人々はほとんどが示唆されている

select c.*, i.* 
    from Customer c 
    left join Invoice i on c.ID = i.CustomerID 

から:

var q = from c in Customers 
     join i in Invoices.DefaultIfEmpty() on c.ID equals i.CustomerID 
     select new { c, i }; 

私は本当にこれが唯一の方法であることができる方法を理解していません。 CustomerInvoiceの関係は、LinqToSQLクラスによってすでに定義されています。なぜ私はjoin句のためにそれを繰り返さなければならないのですか?もし私が内部の参加を望むならば、それは単純に:

var q = from c in Customers 
     from i in c.Invoices 
     select new { c, i }; 

結合されたフィールドを指定しないで!

私が試した:

var q = from c in Customers 
     from i in c.Invoices.DefaultIfEmpty() 
     select new { c, i }; 

が、それは内部結合であるかのようにちょうど私に同じ結果を与えたことを。

これを行う良い方法はありませんか?

答えて

5

あなたはどういうことを言っていますか?そのfrom i in c.Invoice.DefaultIfEmpty()はちょうど左の結合です。

 List<string> strings = new List<string>() { "Foo", "" }; 

     var q = from s in strings 
       from c in s.DefaultIfEmpty() 
       select new { s, c }; 

     foreach (var x in q) 
     { 
      Console.WriteLine("ValueOfStringIs|{0}| ValueOfCharIs|{1}|", 
       x.s, 
       (int)x.c); 
     } 

このテストでは、生成します。

ValueOfStringIs|Foo| ValueOfCharIs|70| 
ValueOfStringIs|Foo| ValueOfCharIs|111| 
ValueOfStringIs|Foo| ValueOfCharIs|111| 
ValueOfStringIs|| ValueOfCharIs|0| 
+1

よく吹き飛ばす - あなたは正しい!さて、なぜ私はこれがうまくいかないと思ったのですか? OK、私は謙虚に戻りました...この質問は私自身の誤解の結果でした。ありがとう! :) –

2

おそらく、 'into'キーワードを使用することができます。

Example

+0

おかげで、これは本当に私の質問に答えていない...関係がすでに定義されているという事実を利用して、より良い方法はありませんか? –

6

関係は既にそれがその関係を使用するべきかを自動的に決定することができない(データベースと.dbmlマークアップの両方で)実行時に定義されているが。

オブジェクトモデルに2つの関係がある場合(Personには親と子があり、両方とも他のPersonインスタンスとの関係)ケースは特別な場合があるかもしれませんが、これによりシステムが複雑になります(バグが増えます)。 SQLでは、関係の指定を繰り返すことを忘れないでください。

インデックスとキーは実装の詳細であり、リレーションモデルの基礎となる関係代数の一部ではないことを覚えておいてください。

あなたはLEFT OUTER JOINをしたいなら、あなたは "into" を使用する必要があります。

from c in Customers 
join i in Invoices on i.CustomerId equals c.CustomerId into inv 
... 

とINVは、おそらくいないインスタンスと、タイプIEnumerable<Invoivce>を持つことになります。

+0

+1いい答えですが、あなたはまだ私の意見が不足しています。請求書には特に「得意先」関係が定義されており、「請求書」だけでなく、「c.Invoices」というTHAT関係を使用したいと考えています。それを行う方法はありますか? –

+0

@Shaul:それでは、式にc.Invoicesを使用してください。異なる識別子が必要な場合は、let節を使用します。 – Richard