2016-04-06 6 views
0

これはちょっと混乱した質問ですが、私の頭の中では論理を正しく取得できません。多対多の関係では、あるエンティティが別のエンティティに限定されていることを確認してください。

私は3つのテーブルTableA,TableBおよびを持っています。私はTableBのレコードがTableAの単一のレコードにのみ結び付けられているTableABBridgeからすべての値を取得する必要があります。

私は、ユーザーがTableAの値の特定のプロパティを編集できるツールを持っています。しかし、TableBも同じプロパティを持ち、TableAのエンティティのプロパティと同期させておく必要があります。したがって、TableAの値を更新すると、特定のエンティティにリンクされたTableBの値はすべて更新する必要がありますが、TableBのエンティティがTableAの1つのエンティティにのみリンクされている場合のみ更新する必要があります。

ですから、例えば上記の例では

TableAの

| ID | Prop | 
|-------------------| 
|  1|   1| 
|  2|   3| 
|  3|   3| 
|-------------------| 

TableBの

| ID | Prop | 
|-------------------| 
|  1|   1| 
|  2|   1| 
|  3|   3| 
|  4|   1| 
|-------------------| 

TableABBridge

| AId | BId | 
|-------------------| 
|  1|  1| 
|  1|  2| 
|  1|  4| 
|  2|  3| 
|  3|  3| 
|-------------------| 

のために、私はにプロパティを編集することができるだろうIDの場合のの値がIDの場合のみ、1,2および4はTableAからID1に限定されています。ただし、TableBの共通エンティティを共有しているため、ID 2または3のプロパティを編集することはできません。

Linqを使用して、のIDのリストを取得する方法を理解する必要があります。これは、TableABBridgeを照会して編集できるようにしています。

これを達成するためのSQLは次のとおりです。

SELECT MAX(AId), BId 
FROM TableABBridge 
GROUP BY BId 
HAVING Count(AId) = 1 

SELECT a.Id 
FROM TableABBridge a 
JOIN 
    (SELECT BId 
    FROM TableABBridge 
    GROUP BY BId 
    HAVING Count(AId) > 1) b ON b.BId = a.BId 
+0

Linqの同等の機能は、Join Statementです。参照:https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b – jdweng

+1

明示的または暗黙的な「リンク」(ブリッジ)テーブルを使用していますか?なぜあなたはエンティティモデルの関連部分を投稿しないのですか? –

+0

実際には3つのエンティティの間に明示的なリンクがあります。したがって、 'TableA'からの値は' TableABBridge'へと 'TableB'へ、そしてその逆の値は' TableABBridge'へ、そして 'TableB'から。 –

答えて

0

A LINQ-これを行う方法はこれです:

var diffs = from b in context.Bs 
      where b.ABs.Count() == 1 
      let a = b.ABs.FistOrDefault().A 
      where a.Prop != b.Prop 
      select new { b, ValueA = a.Prop }; 

foreach(var diff in diffs) 
{ 
    diff.b.Prop = diff.ValueA; 
} 

context.Bs where b.ABs.Count() == 1は、すべて1つのジャンクションレコードを持つBsを返します。つまり、Aです。次に、BとAの値が並べて格納されている構造体が作成されるため、ループ内での更新は簡単です。

「LINQ-ish」と言いました。なぜなら、LINQで自然に表現する方法が、SQLでもっと明白なものとは異なる場合があるからです(b.ABs.Count()GROUP BY)。カウントのためにサブクエリが生成され、グループ化よりも効率が低下する可能性があります。ただし、LINQ group byは必ずしもSQL GROUP BYに翻訳されるとは限らないことに注意してください。

0

(また、必要に応じて)逆私は1つの可能な解決策があることと考えている:

var bridges = context.TableABBridge.Select(n => new 
{ 
    n.AId, 
    n.BId 
}).Distinct() 
.GroupBy(n => n.BId, n => n.AId).Where(n => n.Count() > 1) 
.Select(n=>n.Key); 

var uneditable = context.TableABBridge.Where(n => bridges.Contains(n.BId)).Select(n => n.AId); 

var editable = context.TableABBridge.Select(n => new 
{ 
    n.AId, 
    n.BId 
}).Distinct() 
.GroupBy(n => n.BId, n => n.AId).Where(n => n.Count() == 1) 
.Select(n => n.FirstOrDefault().Value); 
関連する問題