2014-07-06 4 views
4

Я пытаюсь пропустить все DbSets в моем DbContext, которые содержат объекты с определенным базовым типом. Моя цель - использовать этот цикл до того, как я вызову SaveChanges в моем DbContext и установил некоторые параметры по умолчанию.Entity Framework DbSet Reflection

В C#, мой базовый класс выглядит следующим образом: -

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

    public DateTime Modified { get; set; } 
} 

Примером производного класса является: -

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

    public string Name { get; set; } 
} 

Я создал метод пользовательских SaveChanges в моем классе DbContext и может получить список ProtertyInfo для каждого DbSet, содержащего TrackedEntity, но когда я пытаюсь пропустить значения в каждом DbSet, я получаю сообщение об ошибке, поскольку я не могу отбросить свой DbSet производного класса (например, DbSet < Record>) на DbSet базового класса (например, 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; 
    } 
} 

Кто-нибудь знает, возможно ли то, что я пытаюсь достичь?

ответ

3

Вместо этого вы должны использовать ChangeTracker.

.... 
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

Отлично, спасибо! – user1573618

Смежные вопросы