Entity Framework DbSet Reflection
c#, entity-framework, reflection
Solution
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();
Problem
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 (e.g. DbSet< Record >) to a DbSet of the base class (e.g. 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?