3

I am working on a method that compares two objects using reflection. The object types are objects created from entity framework. When I use GetProperties() I am getting EntityCollection and EntityReference properties. I only want the properties that belong to the object and not any associated properties or references from foreign keys.

I've tried the following How to get all names of properties in an Entity?.

I thought about passing an array of properties to compare but I don't want to have to type them in for each object type. I am open to some suggestions even those that don't use reflection.

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;
}
Community
  • 1
  • 1
wsamoht
  • 1,618
  • 1
  • 13
  • 14

3 Answers3

4

Using the suggestions from @Eranga and https://stackoverflow.com/a/5381986/1129035 I was able to come up with a workable solution.

Since some of the properties in the root object are a GenericType there needs to be two different if statements. Only if the current property is an EntityCollection skip over it.

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;
}
Community
  • 1
  • 1
wsamoht
  • 1,618
  • 1
  • 13
  • 14
2

make it easy for yourself and do this instead

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

alex
  • 21
  • 1
2

Try filtering out EntityObject type and EntityCollection properties.

var properties = oldEntity.GetType().GetProperties().
                   Where(pi => !(pi.PropertyType.IsSubclassOf(typeof(EntityObject))
                   || pi.PropertyType.IsSubclassOf(typeof(EntityCollection));
Eranga
  • 32,181
  • 5
  • 97
  • 96
  • EntityCollection requires a type to be set. – wsamoht Jan 04 '12 at 04:47
  • Sorry trying to figure out stackoverflow :) I changed to this: `PropertyInfo[] properties = oldEntity.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance).Where(pi => !(pi.PropertyType.IsSubclassOf(typeof(EntityObject))) && !(pi.PropertyType.IsSubclassOf(typeof(EntityReference)))).ToArray();` Now only EntityCollections need to be excluded. – wsamoht Jan 04 '12 at 04:51
  • My question now is how to remove the EntityCollection objects from the property list – wsamoht Jan 04 '12 at 17:34
  • @curiousg modify the `Where` condition to filter out `EntityCollection`. – Eranga Jan 05 '12 at 00:12