【问题标题】:Get entity object's property names excluding entitycollection and entityreference获取实体对象的属性名称,不包括 entitycollection 和 entityreference
【发布时间】:2015-09-03 05:14:39
【问题描述】:

我正在研究一种使用反射比较两个对象的方法。对象类型是从实体框架创建的对象。当我使用 GetProperties() 时,我得到了 EntityCollection 和 EntityReference 属性。我只想要属于该对象的属性,而不想要任何关联的属性或来自外键的引用。

我尝试了以下How to get all names of properties in an Entity?

我考虑过传递一组属性进行比较,但我不想为每个对象类型都输入它们。我愿意接受一些建议,即使是那些不使用反射的建议。

public bool CompareEntities<T>(T oldEntity, T newEntity)
{
    bool same = true;
    PropertyInfo[] properties = oldEntity.GetType().GetProperties();

    foreach (PropertyInfo property in properties)
    {
        var oldValue = property.GetValue(oldEntity, null);
        var newValue = property.GetValue(newEntity, null);

        if (oldValue != null && newValue != null)
        {
            if (!oldValue.Equals(newValue))
            {
                same = false;
                break;
            }
        }
        else if ((oldValue == null && newValue != null) || (oldValue != null && newValue == null))
        {
            same = false;
            break;
        }
    }
    return same;
}

【问题讨论】:

  • 这些实体是 POCO 还是派生自 EntityObject

标签: c#-4.0 entity-framework-4


【解决方案1】:

根据@Eranga 和https://stackoverflow.com/a/5381986/1129035 的建议,我想出了一个可行的解决方案。

由于根对象中的某些属性是 GenericType,因此需要两个不同的 if 语句。仅当当前属性是 EntityCollection 时才跳过它。

public bool CompareEntities<T>(T oldEntity, T newEntity)
{
    bool same = true;
    PropertyInfo[] properties = oldEntity.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
        .Where(pi => !(pi.PropertyType.IsSubclassOf(typeof(EntityObject)))
        && !(pi.PropertyType.IsSubclassOf(typeof(EntityReference)))
        ).ToArray();

    foreach (PropertyInfo property in properties)
    {
        if (property.PropertyType.IsGenericType)
        {
            if (property.PropertyType.GetGenericTypeDefinition() == typeof(EntityCollection<>))
            {
                continue;
            }
        }

        var oldValue = property.GetValue(oldEntity, null);
        var newValue = property.GetValue(newEntity, null);

        if (oldValue != null && newValue != null)
        {
            if (!oldValue.Equals(newValue))
            {
                same = false;
                break;
            }
        }
        else if ((oldValue == null && newValue != null) || (oldValue != null && newValue == null))
        {
            same = false;
            break;
        }
    }

    return same;
}

【讨论】:

    【解决方案2】:

    尝试过滤掉EntityObject 类型和EntityCollection 属性。

    var properties = oldEntity.GetType().GetProperties().
                       Where(pi => !(pi.PropertyType.IsSubclassOf(typeof(EntityObject))
                       || pi.PropertyType.IsSubclassOf(typeof(EntityCollection));
    

    【讨论】:

    • EntityCollection 需要设置类型。
    • 对不起,试图找出 stackoverflow :) 我改为:PropertyInfo[] properties = oldEntity.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance).Where(pi =&gt; !(pi.PropertyType.IsSubclassOf(typeof(EntityObject))) &amp;&amp; !(pi.PropertyType.IsSubclassOf(typeof(EntityReference)))).ToArray(); 现在只需要排除 EntityCollections。
    • 我现在的问题是如何从属性列表中删除 EntityCollection 对象
    • @curiousg 修改Where 条件以过滤掉EntityCollection
    【解决方案3】:

    让自己轻松一点,然后改为这样做

    PropertyInfo[] 属性 = oldEntity.GetType().GetProperties(pi=> pi.PropertyType.NameSpace=="System").ToArray();

    【讨论】:

    • 你摇滚。这解决了我自己的问题:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多