有没有一种方法可以比较两个实体中的所有值
本文关键字:实体 两个 比较 一种 方法 有没有 | 更新日期: 2023-09-27 18:22:02
我使用的是EF4.3,所以我指的是实体,但它可以应用于任何包含属性的类。
我想弄清楚是否可以比较两个实体。为了清楚起见,每个实体都有被赋值的属性,比如说该实体是"客户"。
public partial class Customer
{
public string Name { get; set; }
public DateTime DateOfBirth { get; set; }
...
...
}
客户访问我的网站并键入一些详细信息"TypedCustomer"。我对照数据库进行检查,如果其中一些数据匹配,我会从数据库"StoredCustomer"返回一条记录。
因此,在这一点上,我已经确定是同一位客户返回,但我不想验证其余数据。我可以逐一检查每一处房产,但也有相当多的房产需要检查。有没有可能在更高的水平上进行比较,考虑到每个人的当前值?
if(TypedCustomer == StoredCustomer)
{
.... do something
}
如果您将这些东西存储在数据库中,那么可以合理地假设您还拥有一个名为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)
{
}
更新:
在我的项目中,我有一个比较这些情况的工具:
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
最简单的方法似乎是使用反射:获取要比较的属性和/或字段,并循环使用它们来比较两个对象
这将通过getType(Customer).getProperties和getType(Customer.getFields来完成,然后在每个字段/属性上使用getValue并进行比较
您可能希望将自定义信息添加到字段/属性中,以定义需要的信息比较。这可以通过定义AttributeUsageAttribute来实现,例如,它将继承自FlagsAttribute。然后,您必须在isEqualTo方法中检索和处理这些属性。
我认为在这种情况下检查整个对象没有多大意义——他们必须像以前一样完全键入每个属性,而简单的"它们匹配吗"并不能告诉你很多。但假设这是你想要的,我可以看到几种方法:
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;