0

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

我试图弄清楚是否可以比较 2 个实体。为清楚起见,每个实体都具有分配值的属性,假设实体是“客户”。

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

客户访问我的网站并输入一些详细信息“TypedCustomer”。我对照数据库进行检查,如果某些数据匹配,我会从数据库“StoredCustomer”返回一条记录。

因此,在这一点上,我已经确定返回的是同一位客户,但我不想验证其余数据。我可以逐一检查每个属性,但要检查的却很少。是否可以在考虑每个当前值的更高级别进行此比较?

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

3 回答 3

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
于 2013-07-11T14:55:36.377 回答
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;
于 2013-07-11T15:02:46.047 回答
0

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

于 2013-07-11T15:02:51.897 回答