2016-12-07 22 views
1

同じクラスのオブジェクトを含む2つのリストを比較する必要がありますが、違いを確認するためにすべてのプロパティを使用する必要はありません。例えば。 Id(主キー)プロパティは使用しないでください。C#2つの一致リストの相違点を取得

は私の例クラス:私は上記でやりたい何

class MyClass 
{ 
    public System.Nullable<int> Id { get; set; } 
    public int VMId { get; set; } 
    public string Name { get; set; } 
} 

var oldR = new List<MyClass>(); 
oldR.Add(new MyClass() { Id = 1, VMId = 11, Name = "Test1" }); 
oldR.Add(new MyClass() { Id = 2, VMId = 22, Name = "Test2" }); 
oldR.Add(new MyClass() { Id = 3, VMId = 33, Name = "Test3" }); 
oldR.Add(new MyClass() { Id = 4, VMId = 44, Name = "Test4" }); 
oldR.Add(new MyClass() { Id = 5, VMId = 55, Name = "Test5" }); 

var newR = new List<MyClass>(); 
newR.Add(new MyClass() { Id = null, VMId = 22, Name = "Test2" }); 
newR.Add(new MyClass() { Id = null, VMId = 33, Name = "Test3" }); 
newR.Add(new MyClass() { Id = null, VMId = 44, Name = "Test43" }); 
newR.Add(new MyClass() { Id = null, VMId = 55, Name = "Test5" }); 
newR.Add(new MyClass() { Id = null, VMId = 66, Name = "Test6" }); 

は、VMID特性上の2つのリストを一致させることです。次にNameプロパティがoldRからnewRに変更されているかどうか確認したいと思います。

基本的には、まずTest1をデータベースから削除し、Test6を追加し、Test4をTest43に更新する必要があります。私は私の本当のクラスは20の特性を持っていることを言及する必要があり :

は、それがローミングサービス

はEDITなります願っています。私はlinqを使って比較する方法を今、すべて指定することなくしたいと思いますか?そして、おそらく、私が比較したくないIdプロパティを除外してください。

どうすればいいですか?

+0

linqクエリを試してください。それはあなたが簡単にオブジェクトを比較するのに役立ちます –

+0

私の本当のクラスは+20のプロパティを持っていることを言及する必要があります。私はlinqを使って比較する方法を今、すべて指定することなくしたいと思いますか?そして、おそらく、私が比較したくないIdプロパティを除外する – user1281991

+0

リストVMIDを結合するために左外部結合を使用します。 msdn:https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b – jdweng

答えて

2

それはあなたが[i]を.Equals(newR)oldRを行うことができますので、これは重要になります。このスレッドimplement equatable

に見てください。すべてのオブジェクトをチェックし、どの項目を削除し、どの項目を追加すべきかのリストを吐き出すネストされたforeachを使うだけです(removeListとaddListでこれを行うことができます)。もしあなたがlinqルートに行くなら、iequatableを有益にする必要があり、linqクエリは書く方が簡単です。

3

C#でこの種の作業を行うための標準的な方法がいくつかあります。

比較するクラスを制御できる場合は、IEquatable<T>インターフェイスを実装し、Object.Equalsメソッドをオーバーロードしてインスタンスの比較方法を定義できます。またと他のハッシュコレクションの等価性が正しく働くように、Object.GetHashCodeを上書きする必要があります。

例:

class MyClass : IEquatable<MyClass> { 

    public string name; 
    public int primaryKey; 

    //IEquatable<T> implementation 
    public bool Equals(MyClass other) => 
     !Equals(other, null) 
     && other.name == this.name; 

    //Overriding Object methods 
    public override bool Equals(object other) => 
     Equals(other as MyClass); 

    public override int GetHashCode() => name.GetHashCode(); 
} 

あなたは、そのクラスのコントロールを持っていない場合は、別のクラスのインスタンスを比較することができIEqualityComparer<T>インタフェースを実装するクラスを作成することができます。

例:

class MyComparer : IEqualityComaprer<MyClass> { 
    public bool Equals(MyClass a, MyClass b) { 
     if (Object.Equals(a, null)) return Object.Equals(b, null); 
     if (Object.Equals(b, null)) return false; 
     return a.name == b.name; 
    } 

    public int GetHashCode(MyClass obj) => obj.name.GetHashCode(); 
} 

標準のLINQの演算子の多くは、要素の比較のためIEqualityComparersなどの追加パラメータを受け入れるオーバーロードを持っています。

+1

' IEqualityComparer <> '** **常に**必要な関数に必要な比較関数を提供します。'Equals()'と 'GetHashCode()'をオーバーライドすると、デフォルトの動作が変更され、別のコンテキストでクラスを使用すると予期しない動作につながる可能性があります。 – Oliver

+0

@Oliverは良い点を示しています。 'IEquatable'は、そのタイプのデフォルト比較を定義することです。そのクラスの1つの特定の用途だけのニーズを満たすために、それを使用しないでください。 'IEqualityComparer'は、特定の非標準比較を必要とする状況の方がはるかに優れています。 – JamesFaix

関連する問題