Reputation: 12376
The title covers a very tiny part of what I'm trying to achieve, so be informed ahead. I'm trying to build a generic way of properly updating collection properties of an entity when that entity itself is updated. In the nutshell I want to do something similar to the approach explained here but I want to go generic way. For that I have created an attribute called EntityCollectionPropertyAttribute
and marked those properties of entities that
I need to be updated too. Here's an example:
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
}
}
}
Lets say the parent entity that has been updated is a Student. Besides Name (and possibly ID) properties, I need the Teachers to be updated as well. So in the commented area I need something like this:
var updatedTeachers=studentEntity.Teachers.ToList();
but of course generic way. I will also have to look inside the DbContext for the teachers DBSet independently. So I will need something like this too:
var exisitingTeachers=MyDbContext.Teachers.ToList();
Any ideas how to do this?
Upvotes: 1
Views: 1415
Reputation: 3231
You can call ToList
method by passing property value prop.GetValue(entity)
in this method:
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 });
}
In this way you will be able to iterate through collection.
If type of property value List
or Array
and there is no need in creating new collection you can just cast value to IList
and iterate through it.
For getting values from database context you can use Set
method:
var dbset = MyDbContext.Set(prop.PropertyType.GenericTypeArguments.First());
dbset
also could be passed to CollectionToList
method, but in that way you will load all table rows from table which could take a lot of time and memory.
Upvotes: 1