[英]How to iterate through an ICollection type property with reflection
标题仅涵盖了我要实现的目标中很小的一部分,因此请提前告知。 我正在尝试建立一种在实体本身更新时正确更新其集合属性的通用方法。 简而言之,我想做一些与这里说明的方法类似的事情,但我想采用通用的方法。 为此,我创建了一个名为EntityCollectionPropertyAttribute
的属性,并标记了我也需要更新的实体的那些属性。 这是一个例子:
public class Teacher{
public int TeacherId{get;set;}
public string Name{get;set;}
}
public class Student{
public int StudentId{get;set;}
public string Name {get;set;}
[EntityCollectionProperty]
public virtual ICollection<Teacher> Teachers{get;set;}
}
public bool IsPropertyAnEntityCollection(PropertyInfo prop){
return Attribute.IsDefined(prop, typeof(EntityCollectionPropertyAttribute));
}
public void Update<T>(T entity)where T:class{
DbEntityEntry entry = MyDbContext.Entry(entity);
foreach (var prop in entry.Entity.GetType().GetProperties())
{
if(IsPropertyAnEntityCollection(prop)){
//Here's where I get stuck
}
}
}
假设已更新的父实体是学生。 除了名称(可能还有ID)属性外,我还需要更新教师。 因此,在评论区域中,我需要这样的东西:
var updatedTeachers=studentEntity.Teachers.ToList();
但当然是通用方式。 我还必须单独在DbContext内部查找教师DBSet。 所以我也需要这样的东西:
var exisitingTeachers=MyDbContext.Teachers.ToList();
任何想法如何做到这一点?
您可以通过在此方法中传递属性值prop.GetValue(entity)
来调用ToList
方法:
private IList CollectionToList(object value)
{
var collectionType = value.GetType().GenericTypeArguments.First();
var method = typeof(Enumerable).GetMethod("ToList");
var genericMethod = method.MakeGenericMethod(collectionType);
return (IList)genericMethod.Invoke(null, new[] { value });
}
这样,您就可以遍历集合。 如果属性的类型为List
或Array
并且不需要创建新的集合,则可以将值IList
为IList
并对其进行迭代。
为了从数据库上下文中获取值,可以使用Set
方法:
var dbset = MyDbContext.Set(prop.PropertyType.GenericTypeArguments.First());
dbset
也可以传递给CollectionToList
方法,但是通过这种方式,您将从表中加载所有表行,这可能会花费大量时间和内存。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.