I am trying to loop through all the DbSets in my DbContext that contain entities with a certain base type. My aim is to use this loop before I call SaveChanges on my DbContext and set some default parameters.
In C#, my base class looks like this:-
public abstract class TrackedEntity
{
public string ModifiedBy { get; set; }
public DateTime Modified { get; set; }
}
An example of a derived class is:-
public class Record : TrackedEntity
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
}
I have created a custom SaveChanges method in my DbContext class and can get a list of ProtertyInfo for each DbSet containing a TrackedEntity, but when I try to loop through the values in each DbSet I get an error as I can't cast my DbSet of derived class (eg DbSet< Record >) to a DbSet of the base class (eg DbSet< TrackedEntity >).
public class MyContext : DbContext
{
public DbSet<Record> Records { get; set; }
public int SaveChanges(string username)
{
//Set TrackedEnity update columns
foreach (PropertyInfo property in GetDbSetPropertyInfos<TrackedEntity>())
{
foreach (TrackedEntity entity in (DbSet<TrackedEntity>)property.GetValue(this, null)) //fails here due to cast
{
entity.Modified = DateTime.UtcNow;
entity.ModifiedBy = username;
}
}
return base.SaveChanges();
}
//return a list of PropertyInfo for each DbSet with a given type in this context
IEnumerable<PropertyInfo> GetDbSetPropertyInfos<T>() where T : class
{
IEnumerable<PropertyInfo> properties = GetType().GetProperties().Where(p => p.PropertyType.IsGenericType
&& p.PropertyType.Name.StartsWith("DbSet")
&& p.PropertyType.GetGenericArguments().Length > 0
&& p.PropertyType.GetGenericArguments()[0].IsSubclassOf(typeof(T)));
return properties;
}
}
Does anyone know if what I am trying to achieve is possible?
You should use ChangeTracker instead.
....
foreach( var entry in context.ChangeTracker.Entries<TrackedEntity>())
{
if(entry.State!=EntityState.Unchanged)
{
TrackedEntity entity = entry.Entity;
entity.Modified = DateTime.UtcNow;
entity.ModifiedBy = username;
}
}
context.SaveChanges();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.