2016-05-20 5 views
4

のジョイン:MaterialByOperatorLINQ - 左私はこのように定義された三つのクラス持つ3 ObservableCollections

public class MaterialByOperator 
{ 
    public int IdOperator{ get; set; } 
    public int IdMaterial { get; set;} 
} 

public class Material 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

public class AssignedOperator 
{ 
    public int idOperation { get; set; } 
    public int idOperator { get; set; } 
} 

IdMaterialMaterialのための "ForeignKeyの" です。関係はOne to Manyです。

IdOperatorMaterialByOperatorは、One to One関係のAssignedOperatorの「ForeignKey」です。

は、その後、私はこの3 ObservableCollectionを定義します。

public ObservableCollection<Material> Materials; 
public ObservableCollection<MaterialByOperator> MaterialsXOperator; 
public ObservableCollection<AssignedOperator> AssignedOperators; 

私が欲しいものの任意の材料がasigned持っていない事業​​者名を取得することです。

var mate = MaterialsXOperator.GroupBy(x => x.idOperator); //Group materials by operatorId 
//left join assignedOperators with the grouped materials 
var opeasigmate = AssignedOperators.GroupJoin(mate, oper => oper.idOperator, 
        grupo => grupo.Key, (oper, grupo) => new { oper, grupo }); 
var operWithoutmate = opeasigmate.Where(x => x.grupo.Count() == 0); 

私のLINQの知識は非常に広いではないとして、私は、知って欲しい(私は何年も私の仕事でそれを禁じられていたが、それを信じるかどうか)のいずれかの最も簡単な方法があります:私は今、このようにそれを行います私が欲しいものを実現する?私が言ったように、私のソリューションは機能しますが、私はうまくいけば勉強するために他の視点を見たいと思います。

var operWithoutmate = AssignedOperators 
    .Where(ao => !MaterialsXOperator.Any(mo => mo.IdOperator == ao.idOperator); 

しかし、一般的にjoinを使用すると、より効率的であるので、私はあなたがそのように維持することをお勧め:Anyを使用して

+0

あなたは操作を実行する:

var operWithoutmate = AssignedOperators .GroupJoin(MaterialsXOperator, ao => ao.idOperator, mo => mo.IdOperator, (ao, moGroup) => new { ao, moGroup }) .Where(r => !r.moGroup.Any()) .Select(r => r.ao); 

私は個人的に関与ジョインがある場合、簡単に、読みやすくするためにクエリ構文を見つけますDBまたはメモリ内のデータに対してクラスにOperatorの説明がありません。OperatorIdだけがありますが、名前が必要です。 IdOperationとは何ですか? – 3615

+0

'Any'を使って簡単な方法がありますが、あなたが最も効率的ですので、そのまま使用します。 –

+0

これは、より広いワーキングコードからの最小の例に過ぎません。もちろん、私はオペレータ名を持っていますが、サンプルは無関係です。問題は、3つのobservablecollectionsを結合して、オペレータが材料を割り当てずにオペレーションに割り当てられることです。私は知っている少し複雑なサンプルです。メモリまたはDBに対する操作は無関係ですが、サンプルではメモリ内にあると仮定します。 – Pikoh

答えて

2

は間違いなく簡単です。唯一の改善点は、x.grupo.Count() == 0!x.grupo.Any()に置き換えることです。この場合にもGroupByが冗長であるため、クエリは次のようになります。

var operWithoutmate = 
    from ao in AssignedOperators 
    join mo in MaterialsXOperator on ao.idOperator equals mo.IdOperator into moGroup 
    where !moGroup.Any() 
    select ao; 
+0

それは非常に興味深い解決策です。そして、間違いなく提案された改善は非常に良いです。私が間違っていなければ、 'Count()'はすべての結果を繰り返し、 'Any()'は結果を返しません。 – Pikoh

+0

正しい。ポケットが空かどうかを知るためにあなたのポケットのコインを数える必要はありません:) –

+0

もう一度やっぱり...私は別の答えがあるかどうかを確認するために数分待って、私はあなたを受け入れるでしょう。 – Pikoh

関連する問題