2013-07-11 65 views
0

我使用EF4.3,所以我指的是實體,但它可以應用於任何包含屬性的類。有沒有比較2個實體內所有值的方法?

我想弄清楚是否有可能比較2個實體。每個實體都有屬性,這些屬性被賦予了明確的值,假設實體是「客戶」。

public partial class Customer 
{ 
    public string Name { get; set; } 
    public DateTime DateOfBirth { get; set; } 
    ... 
    ... 
} 

客戶訪問在一些細節上「TypedCustomer」我的網站和類型。我根據數據庫檢查了這一點,如果某些數據匹配,我從數據庫'StoredCustomer'返回一條記錄。

所以在這一點上,我已經確定它的客戶返回的是同一個客戶,但我不想驗證其餘的數據。我可以逐個檢查每個房產,但是有一些可以檢查。是否有可能在考慮每個當前值的較高級別進行比較?

if(TypedCustomer == StoredCustomer) 
{ 
    .... do something 
} 
+0

爲什麼不重新加載數據?如果它仍然在記憶中,是否有人或其他人修改了它?什麼會使數據「有效」,什麼會使其無效? – Winks

回答

1

如果你在數據庫中存儲這些東西,這是合乎邏輯的假設,你也不得不叫像Id主鍵。

public partial class Customer 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public DateTime DateOfBirth { get; set; } 
    ... 
    ... 
} 

然後你要做的就是:

if(TypedCustomer.Id == StoredCustomer.Id) 
{ 
} 

UPDATE:

在我的項目,我有這些情況下,比較器:

public sealed class POCOComparer<TPOCO> : IEqualityComparer<TPOCO> where TPOCO : class 
{ 
    public bool Equals(TPOCO poco1, TPOCO poco2) 
    { 
     if (poco1 != null && poco2 != null) 
     { 
      bool areSame = true; 
      foreach(var property in typeof(TPOCO).GetPublicProperties()) 
       { 
        object v1 = property.GetValue(poco1, null); 
        object v2 = property.GetValue(poco2, null); 
        if (!object.Equals(v1, v2)) 
        { 
         areSame = false; 
         break; 
        } 
       }); 
      return areSame; 
     } 
     return poco1 == poco2; 
    } // eo Equals 

    public int GetHashCode(TPOCO poco) 
    { 
     int hash = 0; 
     foreach(var property in typeof(TPOCO).GetPublicProperties()) 
     { 
      object val = property.GetValue(poco, null); 
      hash += (val == null ? 0 : val.GetHashCode()); 
     }); 
     return hash; 
    } // eo GetHashCode 
} // eo class POCOComparer 

用途的擴展方法:

public static partial class TypeExtensionMethods 
{ 
    public static PropertyInfo[] GetPublicProperties(this Type self) 
    { 
     self.ThrowIfDefault("self"); 
     return self.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where((property) => property.GetIndexParameters().Length == 0 && property.CanRead && property.CanWrite).ToArray(); 
    } // eo GetPublicProperties 


} // eo class TypeExtensionMethods 
+0

那不是我想要的。客戶可能是一樣的,但是例如他們可能已經更新了他們的手機號碼。 – dotnetnoob

+0

@dotnetnoob,請參閱編輯。 –

0

我不認爲在這種情況下檢查整個對象是有很多目的的 - 他們必須完全按照以前的方式輸入每個屬性,而且一個簡單的「它們匹配」並不是真的告訴你很多。但假設這就是你想要的,我可以看到幾種方法:

1)只是咬緊牙關,比較每個字段。您可以通過覆蓋bool Equals方法或IEquatable<T>.Equals或僅使用自定義方法來執行此操作。

2)反射,通過屬性循環 - 如果您的屬性是簡單的數據字段,則很簡單,但如果您有複雜的類型需要擔心,則更爲複雜。

foreach (var prop in typeof(Customer).GetProperties()) { 
    // needs better property and value validation 
    bool propertyMatches = prop.GetValue(cust1, null) 
     .Equals(prop.GetValue(cust2, null)); 
} 

3)序列化 - 將兩個對象序列化爲XML或JSON,並比較字符串。

// JSON.NET 
string s1 = JsonConvert.SerializeObject(cust1); 
string s2 = JsonConvert.SerializeObject(cust2); 
bool match = s1 == s2; 
0

最簡單的似乎是使用反射:獲取您想要比較的屬性和/或字段,並通過它們循環來比較你的兩個對象。
這將通過getType(Customer).getProperties和getType(Customer).getFields完成,然後在每個字段/屬性上使用getValue進行比較。
您可能希望將自定義信息添加到您的字段/屬性中,以定義需要比較的字段/屬性。這可以通過定義一個AttributeUsageAttribute完成,例如可以從FlagsAttribute繼承。您將不得不在isEqualTo方法中檢索並處理這些屬性。

相關問題