2012-05-01 70 views
1

的實體框架實體看起來是這樣的:我如何檢查對象的內容相等沒有對象參考平等

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; } 
} 

我拉項目從兩個不同的數據源到IEnumerable的名單。如何比較這些項目而不使用一堆if語句來檢查屬性值之間是否存在差異,然後在屬性值不匹配的情況下設置屬性值?這個想法是保持列表同步。另外,列表A具有設置的ID值,列表B不具有。我只是覺得有一種更好的方法如果你有源對象的控制的話,最好聲明的方式來支持基於價值的平等是實現IEquatable<T>做到這一點比和一幫

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

你可以使用反射創建一個比較功能。檢查數據類型併爲此編寫一些比較代碼。它可能就夠好了。 – CodingBarfield

回答

3

。不幸的是,這需要枚舉所有這些檢查,但是它只在實際的對象定義位置完成,並且不需要在整個代碼庫中重複。

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

另外,你可以選擇重載對象類型的相等操作符讓消費者只需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); 
} 
2

最簡單的方法是提供了一個計算的特定哈希,很像GetHashCode,然後如果兩個實例計算相同的哈希,他們可以說是等同於你的類中的方法。

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(); 
    }