2017-10-17 8 views
1

I T2と多くの関係に多くを持つテーブルT1を持って、参加表はT12で、私はEFとLINQを使用して、T1内のレコードのIdを与え、T2から関連レコードを取得したい、私はそれをやっていますそうですね:EFを使用して結合テーブルの順序との関係を多対多にするか?

var listIds = oContext.T12.Where(x => x.T1Id == id).Select(x => x.T2Id).ToList(); 
//then 
var theList = oContext.T2.In(x => x.Id, listIds).ToList(); 

Inの実装です。

これは、m-t-m関係からデータを照会する最良の方法ではないと思います。 しかし、本当の問題T2からのレコードは、彼らがSQL(アプリケーション内で順状物質)に表示されている順序ではないということです。

enter image description here

が、その順序はT2Idである:58478、58479、58480、58481

EDIT

は私が順番にlistIdsを取得するためにOrderByを使用していますが、リストには、まだ順番に、私はSSMSに行き、そのクエリを行っていない。

SELECT* FROM T2 WHERE Id IN(58481, 58478, 58479, 58480) 

が、これが結果です:

enter image description here

+0

'listIds'は順番にありますか?それ以外は 'OrderBy'を使います。 – aaron

+1

EF 'IQueryable 'で(カスタム) 'IEnumerable '拡張メソッドを使用しないでください。また、2つの照会の必要はありません。ナビゲーションプロパティを定義して使用します。そして、注文が問題であれば、 'OrderBy'を適用してください。' ORDER BY'節なしのSQLクエリの順序は未定義です。 –

+0

編集を参照してください –

答えて

2

あなたの直感が正しいか、それが最善の方法ではありません。 Entity Frameworkで多対多リレーションシップを正しく設定した場合、ジョイングテーブルT12については言及する必要はありません。

Configure Many To Manyを参照してください。あなたのクラスに調整

class T1 
{ 
    public int Id {get; set;} 

    // every T1 has zero or more T2 
    public virtual ICollection<T2> T2s {get; set;} 

    // other properties 
    public int A {get; set;} 
    public string B {get; set;} 
} 

class T2 
{ 
    public int Id {get; set;} 

    // every T2 has zero or more T1 
    public virtual ICollection<T1> T1s {get; set;} 

    // other properties 
    public int C {get; set;} 
    public string D {get; set;} 
} 

public MyDbContext : DbContext 
{ 
    public DbSet<T1> T1s {get; set;} 
    public DbSet<T2> T2s {get; set;} 
} 

すべてです! Entityフレームワークは、T1とT2の間の多対多の関係をモデリングし、追加のデータベーステーブルを作成することを認識します。

linqクエリでは、この余分なテーブルは必要ありません。コレクションにアクセスすると、Linqによって結合が作成されます。

using (var myDbContext = new MyDbContext) 
{ 
    var result = myDbContext.T1s 
     .Where(t1 => t1.X == ...) 
     .Select(t1 = new 
     { 
      // select the T1 properties you want 
      A = t1.A, 
      B = t1.B, 
      // a T1 has zero or more T2s 
      // select the T2s you want: 
      T2s = t1.T2s 
       .Where(t2 => t2.Y == ....) 
       .Select(t2 => new 
       { // Take the T2 properties you want 
        C = t2.C, 
        D = T2.D, 
       }), 
     }); 
} 

ます。また、T2で開始することができ、 "私の財産Xは== ...プロパティY == ...彼のすべてのT2と、すべてのT1与える":

var result = myDbContext.T2s 
     .Where(t2 => t2.Y == ...) 
     .Select(t1 = new 
     { 
      // select the T1 properties you want 
      C = t2.C, 
      D = t2.C, 
      // a T2 has zero or more T1s 
      // select the T1s you want: 
      T1s = t2.T1s 
       .Where(t1 => t1.Y == ....) 
       .Select(t1 => new 
       { // Take the T1 properties you want 
        A = t1.A, 
        B = T2.B, 
       }), 
     }); 

多対多のコレクションプロパティにアクセスするため、Entity Frameworkは、余分に作成された多対多テーブルとの結合を実行する必要があることを認識しています。

結果はGroupJoinに似ています。あなたはそれがグループ化されていない場合は、より本物のようなあなたはほとんど考える必要がない、あなたが適切にあなたの1対多および多対多の関係を定義するたびに、私の経験でSelectMany

var result = MyDbContext.T1s.SelectMany(t1 => t1.T2s 
    .Select(t2 => new 
    { 
     A = t1.A, 
     B = t1.B, 
     C = t2.C, 
     D = t2.D, 
    }); 

を、必要があります参加しますジョインでプロパティにアクセスするだけで、エンティティ・フレームワークは自動的に結合するテーブルを認識します。

+0

あなたの時間のためにHaraldに感謝しますが、私はEF db-firstを使用しています –

関連する問題