1

次のような Entity Framework Entity があります。

class ListItemEtlObject
{
    public int ID { get; set; }
    public string ProjectName { get; set; }
    public string ProjectType { get; set; }
    public string ProjectCode { get; set; }
    public string ProjectDescription { get; set; }
    public string JobNo { get; set; }
    public string JobDescription { get; set; }
    public bool Include { get; set; }
}

2 つの異なるデータ ソースからアイテムを IEnumerable リストにプルしています。一連の if ステートメントを使用せずに項目を比較して、プロパティの値に違いがあるかどうかを確認し、一致しない場合はプロパティの値を設定するにはどうすればよいですか? アイデアは、リストの同期を維持することです。また、リスト A には ID 値が設定されていますが、リスト B には設定されていません。たくさんのよりもこれを行うためのより良い方法があると感じています

if(objectA.ProjectName != objectB.ProjectName)
{
   objectA.ProjectName = objectB.ProjectName;
}
4

3 に答える 3

3

ソース オブジェクトを制御できる場合、値ベースの等価性をサポートするための最善の宣言的な方法は、 を実装することIEquatable<T>です。残念ながら、これらのチェックをすべて列挙する必要がありますが、これは実際のオブジェクト定義の場所で 1 回行われ、コード ベース全体で繰り返す必要はありません。

class ListItemEtlObject : IEquatable<ListITemEtlObject>
{
  ...
  public void Equals(ListITemEtlObject other) {
    if (other == null) {
      return false;
    }
    return 
      ID == other.ID &&
      ProjectName == other.ProjectName &&
      ProjectType == other.ProjectType &&
      ... ;
  }
}

!=さらに、オブジェクト型で等値演算子をオーバーロードし、コンシューマーがインスタンスで単純にand==を使用してListItemEtlObject、参照の等価性ではなく値の等価性を取得できるようにすることもできます。

public static bool operator==(ListItemEtlObject left, ListItemEtlObject right) {
  return EqualityComparer<ListItemEtlObject>.Default.Equals(left, right);
}
public static bool operator!=(ListItemEtlObject left, ListItemEtlObject right) {
  return !(left == right);
}
于 2012-05-01T15:58:59.140 に答える
2

最も簡単な方法は、特定のハッシュを計算するメソッドをクラスに提供するGetHashCodeことです。

于 2012-05-01T15:59:01.420 に答える
1

リフレクションを使用して単純化できます =)

    public virtual void SetDifferences(MyBaseClass compareTo)
    {
        var differences = this.GetDifferentProperties(compareTo);

        differences.ToList().ForEach(x =>
        {
            x.SetValue(this, x.GetValue(compareTo, null), null);
        });
    }

    public virtual IEnumerable<PropertyInfo> GetDifferentProperties(MyBaseClass compareTo)
    {
        var signatureProperties = this.GetType().GetProperties();

        return (from property in signatureProperties
                let valueOfThisObject = property.GetValue(this, null)
                let valueToCompareTo = property.GetValue(compareTo, null)
                where valueOfThisObject != null || valueToCompareTo != null
                where (valueOfThisObject == null ^ valueToCompareTo == null) || (!valueOfThisObject.Equals(valueToCompareTo))
                select property);
    }

そして、ここに私があなたのために行ったいくつかのテストがあります

    [TestMethod]
    public void CheckDifferences()
    {
        var f = new OverridingGetHashCode();
        var g = new OverridingGetHashCode();

        f.GetDifferentProperties(g).Should().NotBeNull().And.BeEmpty();

        f.Include = true;
        f.GetDifferentProperties(g).Should().NotBeNull().And.HaveCount(1).And.Contain(f.GetType().GetProperty("Include"));

        g.Include = true;
        f.GetDifferentProperties(g).Should().NotBeNull().And.BeEmpty();

        g.JobDescription = "my job";
        f.GetDifferentProperties(g).Should().NotBeNull().And.HaveCount(1).And.Contain(f.GetType().GetProperty("JobDescription"));
    }

    [TestMethod]
    public void SetDifferences()
    {
        var f = new OverridingGetHashCode();
        var g = new OverridingGetHashCode();

        g.Include = true;
        f.SetDifferences(g);
        f.GetDifferentProperties(g).Should().NotBeNull().And.BeEmpty();

        f.Include = true;
        g.Include = false;
        f.SetDifferences(g);
        f.GetDifferentProperties(g).Should().NotBeNull().And.BeEmpty();
        f.Include.Should().BeFalse();
    }
于 2012-05-01T17:47:48.513 に答える