Как рекурсивно перебрать свойства сущности - PullRequest
2 голосов
/ 21 марта 2011

Предположим, это то, что у меня есть в моей базе данных


table Ancestor (  
  idAncestor int not null,  
  name varchar(20) not null,  
)  

table Descendant (  
  idDescendant int not null,  
  name varchar(20) not null,  
  Ancestor_idAncestor int not null  
)  

Когда ADO.NET генерирует объект сущности для указанных выше двух таблиц, я могу получить доступ с Descendant из Ancestor через Ancestors.First().Descendants.

Если бы я должен был рекурсивно перебрать потомок (и) предка или потомка (потомков) потомка и распечатать его id и name, моя попытка будет следующей


public void Iterate(Ancestor a)  
{  
   Type t = a.GetType();
   PropertyInfo[] props = t.GetProperties();
   foreach(var prop in props){
      // pseudo code here
      if(prop is entitycollection)
      {
         // how do I convert prop to entity collection here??
         foreach(var p in prop){
            Iterate(p)
         }         
      } else {
         print prop.GetValue(a, null)
      }
   }       
}

Моя проблема заключается в попытке выяснить, относится ли свойство сущности к коллекции сущностей, если оно есть, найти тип, удерживаемый коллекцией, затем выполнить итерацию по типу и т. Д.

Спасибо

1 Ответ

5 голосов
/ 21 марта 2011

Это должна быть грубая версия того, что вы ищете:

private static void recurseAndPrintProperties(Object ObjectToRecurse) {
   foreach (PropertyInfo pi in ObjectToRecurse.GetType().GetProperties()) {
       if ((pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition() == typeof(EntityCollection<>))) {
           IEnumerable collection = (IEnumerable)pi.GetValue(ObjectToRecurse, null);

           foreach (object val in collection)
               recurseAndPrintProperties(val);
       } else {
            if (pi.PropertyType == typeof(Descendant)) {
                Descendant actualDescendant = (Descendant)pi.GetValue(ObjectToRecurse, null);
                Console.WriteLine(actualDescendant.idDescendant + " - " + actualDescendant.Name);
            } else
                Console.WriteLine(pi.Name + "  -  " + pi.GetValue(ObjectToRecurse, null));
       }
   }
}

EDIT

Этот код взят из некоторого кода, с которым я ранее играл для клонирования сущностей. Вот оно (возможно, вам придется изменить его, чтобы учесть, что ваши свойства не дублируются, если они сопоставлены с первичными ключами)

    public static T CloneEntity<T>(T Obj) where T : EntityObject, new() {
        T Clone = new T();

        Type typeToClone = Obj.GetType();
        Type[] BadGenericTypes = new Type[] { typeof(EntityCollection<>), typeof(EntityReference<>) };
        Type[] BadTypes = new Type[] { typeof(System.Data.EntityKey) };

        foreach (PropertyInfo pi in typeToClone.GetProperties().Where(p => p.CanWrite)) {
            if (pi.PropertyType.IsGenericType && BadGenericTypes.Contains(pi.PropertyType.GetGenericTypeDefinition())
                || (BadTypes.Contains(pi.PropertyType))
                || (pi.Name.Equals(Extension.GetPropertyName(() => new FMVHistory().FMVHistoryId), StringComparison.CurrentCultureIgnoreCase)))
                continue;

            pi.SetValue(Clone, pi.GetValue(Obj, null), null);
        }
        return Clone;
    }
...