如何递归迭代实体的属性

发布于 2024-10-25 03:11:37 字数 918 浏览 1 评论 0原文

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


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 个表生成实体对象时,我可以通过 Ancestors.First 访问 Ancestor 的 Descendant ().后代。

如果我要递归地迭代祖先的后代或后代的后代并打印出其 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)
      }
   }       
}

我的问题是尝试确定实体属性是否属于实体集合,如果是,则查找该集合所保存的类型,然后迭代该类型,依此类推。

谢谢

Suppose this is what I have in my database


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  
)  

When ADO.NET generates the entity object for the above 2 tables, I can access Descendant of Ancestor through Ancestors.First().Descendants.

If I were to recursively iterate over an ancestor's descendant(s) or descendant's descendant(s) and print out its id and name, the following is my attempt


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

My problem is trying to figure out if a entity property is of entity collection, if it is, then find the type hold by the collection, then iterate over the type, and so on.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

乄_柒ぐ汐 2024-11-01 03:11:37

这应该是您正在寻找的内容的粗略版本:

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

编辑

此代码来自我之前用于克隆实体的一些代码。就是这样(您可能需要修改它以考虑不复制映射到主键的属性)

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

This should be a crude version of what you're looking for:

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

This code came from some code I had previously played around with for cloning entities. Here it is (you might have to modify it to also take into consideration not duplicating your properties thar are mapped to primary keys)

    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;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文