2012-04-04 21 views
1

私はTSQL + C#土地から来ており、linqとEFに適応しようとしています。多対多の関係が私を驚かせています。私は、データベースから照会したい多対多の関係を持つモデルを持っています。以下のような:Entity Framework:多対多リレーションシップでリンクされたモデルを持つモデルを取得

 class Product{ 
     public int ID {get;set;} 
     public string ProductName {get;set;} 
     public virtual ICollection<Tag> Tags {get;set;} 
    } 

    class Tag { 
     public int ID {get;set;} 
     public string TagName {get;set;} 
     public virtual ICollection<Product> Products {get;set;} 

    } 

私はDbContextのうち、製品自体を取得することができるよ、と、後でそれがこのようなタグを関連付けられていますフェッチ:

// product exists in memory as a Product with an empty product.Tags 

var query = from p in db.Product 
      from t in db.Tags 
      where p.ID == product.ID 
      select p.Tags; 

その後、私はproduct.Tagsを割り当てることができますフェッチされたタグ。明らかに、これは、すべての製品を照会する必要がある場合、複数の製品を扱う際には非常に非効率的です。

linqとEFを使用すると、関連するすべてのタグがデータベースに1回の往復で含まれている製品を取得できます。また、すべての製品と関連するタグ(またはフィルタリングされた製品リスト)を取得できるようにしたいと考えています。どのようにlinqを見ますか?

編集:

[OK]を、いくつかのより多くの周りいじった後、私はこれを持っている:

var query = db.Product.Include("Tags") 
      .Where(p => p.Tags.Any(t => t.Products.Select(m => m.ID).Contains(p.ID))); 

これは私が必要なものはほとんどです。結果はすべてタグ付き商品です。タグがない製品はありません。私はこれをSQL内部結合の同等物と考える。私は、タグを製品に外部結合しておき、オプションのタグを持つすべての製品を返したいと思います。タグがない商品を除外せずに、関連するタグを使ってすべての商品を取得するにはどうすればよいですか?

編集:

これは私が思ったよりも簡単でした。

var query2 = db.Product.Include("Tags").DefaultIfEmpty(); 

これは、タグのない製品を含め、すべての製品とそれぞれのタグを取得します。うまくいけば、それは正しい理由のために働く...

答えて

0

EFのようなオブジェクトリレーショナルマッパーを使用する目的はがあなたのために関係をマップするということです。データベースに外部キーを持つオブジェクトを手動で結合する場合は、間違っています。

自動魔法のようにあなたのための製品とタグに参加しますた、正しい答えは単純context.Products.Include("Tags")である私の質問Why use LINQ Join on a simple one-many relationship?

参照してください。これは文字通りORMを使用する最大の利点です。

関連する問題