有没有一种方法可以比较两个实体中的所有值

本文关键字:实体 两个 比较 一种 方法 有没有 | 更新日期: 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;
相关文章: