如何递归迭代实体的属性

时间:2011-03-21 18:19:31

标签: c# reflection ado.net enumeration

假设这是我在数据库中的内容


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为上述2个表生成实体对象时,我可以通过Descendant访问Ancestor Ancestors.First().Descendants

如果我以递归方式迭代祖先的后代或后代的后代并打印出其idname,以下是我的尝试


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)
      }
   }       
}

我的问题是试图弄清楚实体属性是否属于实体集合,如果是,则找到集合的类型hold,然后迭代该类型,依此类推。

由于

1 个答案:

答案 0 :(得分:5)

这应该是您正在寻找的原始版本:

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));
       }
   }
}

修改

这段代码来自我以前用于克隆实体的一些代码。在这里它是(您可能必须修改它以考虑不重复您的属性thar映射到主键)

    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;
    }