假设这是我在数据库中的内容
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
。
如果我以递归方式迭代祖先的后代或后代的后代并打印出其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)
}
}
}
我的问题是试图弄清楚实体属性是否属于实体集合,如果是,则找到集合的类型hold,然后迭代该类型,依此类推。
由于
答案 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;
}