有没有办法比较2个实体中的所有值?

时间:2013-07-11 14:53:48

标签: c# asp.net entity-framework entity-framework-4

我正在使用EF4.3所以我指的是实体,但它可以应用于任何包含属性的类。

我试图弄清楚它是否可以比较2个实体。为清晰起见,每个实体都具有指定值的属性,即实体为“客户”。

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

客户访问我的网站并输入一些详细信息'TypedCustomer'。我在数据库中检查这一点,如果某些数据匹配,我会从数据库'StoredCustomer'返回一条记录。

所以在这一点上我已经确定它是同一个客户返回但我不想有效的其余数据。我可以逐个查看每个房产,但有一些可以检查。是否有可能在更高的水平上进行比较,并考虑每个的当前值?

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

3 个答案:

答案 0 :(得分: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)
{
}

更新:

在我的项目中,我对这些情况进行了比较:

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

答案 1 :(得分: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;

答案 2 :(得分:0)

最简单的似乎是使用反射:获取您想要比较的属性和/或字段,并循环遍历它们以比较您的两个对象。
这将通过getType(Customer).getProperties和getType(Customer).getFields完成,然后在每个字段/属性上使用getValue并进行比较。
您可能希望向字段/属性添加自定义信息以定义所需的信息 比较。这可以通过定义一个AttributeUsageAttribute来完成,例如,它将继承自FlagsAttribute。然后,您必须在isEqualTo方法中检索和处理这些属性。