2014-07-06 4 views
4

J'essaie de parcourir tous les DbSets de mon DbContext qui contiennent des entités avec un certain type de base. Mon but est d'utiliser cette boucle avant d'appeler SaveChanges sur mon DbContext et de définir des paramètres par défaut.Entity Framework DbSet Reflection

En C#, ma classe de base ressemble à ceci: -

public abstract class TrackedEntity 
{ 
    public string ModifiedBy { get; set; } 

    public DateTime Modified { get; set; } 
} 

Un exemple d'une classe dérivée est: -

public class Record : TrackedEntity 
{ 
    [Key] 
    public int ID { get; set; } 

    public string Name { get; set; } 
} 

J'ai créé une méthode SaveChanges personnalisées dans ma classe DbContext et peut obtenir une liste de ProtertyInfo pour chaque DbSet contenant un TrackedEntity, mais quand j'essaye de faire défiler les valeurs dans chaque DbSet j'obtiens une erreur car je ne peux pas lancer mon DbSet de classe dérivée (par exemple DbSet < Record>) à un DbSet de la classe de base (par exemple DbSet < T rackedEntity>).

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; 
    } 
} 

Est-ce que quelqu'un sait si ce que j'essaie de réaliser est possible?

Répondre

3

Vous devez utiliser ChangeTracker à la place.

.... 
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(); 
+0

Parfait, merci! – user1573618