在属性级别使用通用比较方法扩展EF实体

时间:2013-11-12 11:50:30

标签: c# asp.net entity-framework

public static bool PropertiesEqual<T>(T self, T to, params string[] skip) 
where T : class
{
    if (self != null && to != null)
    {
        var selfType = self.GetType();

        var skipList = new List<string>(skip);
        foreach (PropertyInfo pi in selfType.GetProperties(BindingFlags.Public |
                                                         BindingFlags.Instance))
        {
            if (skipList.Contains(pi.Name)) continue;

            var selfValue = selfType.GetProperty(pi.Name).GetValue(self, null);
            var toValue = selfType.GetProperty(pi.Name).GetValue(to, null);

            if (selfValue != toValue && (selfValue == null ||
                                         !selfValue.Equals(toValue)))
            {
                return false;
            }
        }
            return true;
    }
    return self == to;
}

我想用扩展方法扩展我的EF实体,该方法比较两个实例的原始(?)属性(数字,字符串,bool和非附加对象等属性)。

我想知道的是,是否可以将其作为扩展方法?或者我是否需要在POCO类中为我想要执行的每种EF类型instance1.PropertiesEqual(instance2)定义此内容?

我想知道的第二件事是如何正确地仅针对我上面提到的数据类型,并跳过附加对象(连接表)。

1 个答案:

答案 0 :(得分:2)

要回答您的第一个问题,只要该方法存在于静态类中,您就可以轻松地将其定义为扩展方法。

其次,如果检查Type.IsByRef,您将只获得字符串和结构属性,两者都具有Object.Equals的默认实现。

此实现也会在执行(昂贵的)属性比较之前检查null和相等。

如果您想加快速度,可以使用动态方法进行比较。

public static bool PropertiesEqual<T>(this T self, T other, params string[] skip)
{
    if (self == null) return other == null;
    if (self.Equals(other)) return true;

    var properties = from p in typeof(T).GetProperties()
                        where !skip.Contains(p.Name)
                        && !p.PropertyType.IsByRef // take only structs and string
                        select p;

    foreach (var p in properties)
    {
        var selfValue = p.GetValue(self);
        var otherValue = p.GetValue(other);
        if (!object.Equals(selfValue, otherValue))
            return false;
    }
    return true;
}