Gre*_*egH 6 c# reflection entity-framework
我目前正试图通过覆盖SaveChanges方法和利用反射,以通用的方式在我的应用程序中的所有表上实现历史记录跟踪.作为一个简单的例子,假设我的域对象有2个类/ dbset,每个类的历史表如下:
DbSet<Cat> Cats { get; set; }
DbSet<CatHistory> CatHistories { get; set; }
DbSet<Dog> Dogs { get; set; }
DbSet<DogHistory> DogHistories { get; set; }
Run Code Online (Sandbox Code Playgroud)
本CatHistory类如下所示(DogHistory遵循相同的方案):
public class CatHistory : HistoricalEntity
{
public int CatId { get; set; }
public virtual Cat Cat{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的目标是保存对象时,我想在适当的历史记录表中插入记录.使用反射时,我无法克服类型差异.我目前的尝试是在下面,我似乎被困//TODO:在线上:
var properties = entry.CurrentValues.PropertyNames.Where(x => entry.Property(x).IsModified).ToList();
//get the history entry type from our calculated typeName
var historyType = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(x => x.Name == historyTypeName);
if(historyType != null)
{
//modified entries
if (dbSet != null && historyDbSet != null && entry.State == EntityState.Modified)
{
var existingEntry = dbSet.Find(entry.Property("Id").CurrentValue);
//create history record and add entry to table
var newHistories = GetHistoricalEntities(existingEntry, type, entry);
var listType = typeof(List<>).MakeGenericType(new[] { historyType });
var typedHistories = (IList)Activator.CreateInstance(listType);
//TODO: turn newHistories (type = List<HistoricalEntity>) into specific list type (List<MyObjectHistory>) so I can addrange on appropriate DbSet (MDbSet<MyObjectHistory>)
historyDbSet.AddRange(newHistories);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用AutoMapper来映射您的历史实体。我刚刚创建了一个小测试,希望它能复制您的情况:
IList dogs = new List<Dog>() { new Dog { Id = 1, Name = "Alsatian" }, new Dog { Id = 2, Name = "Westie" } };
var dogHistoryType = typeof(DogHistory);
var listType = typeof(List<>).MakeGenericType(new[] { dogHistoryType });
var typedHistories = (IList)Activator.CreateInstance(listType);
mapper.Map(dogs, typedHistories);
foreach (var historyItem in typedHistories)
{
this.Add(historyItem);
}
Run Code Online (Sandbox Code Playgroud)