c# - 在 SaveChanges 重写中实现历史跟踪

标签 c# entity-framework reflection

我目前正在尝试通过覆盖 SaveChanges 方法并利用反射以通用方式对我的应用程序中的所有表实现历史记录跟踪。作为一个简单的例子,假设我有 2 个类/数据库集用于我的领域对象,每个都有一个历史表,如下所示:

DbSet<Cat> Cats { get; set; }
DbSet<CatHistory> CatHistories { get; set; }
DbSet<Dog> Dogs { get; set; }
DbSet<DogHistory> DogHistories { get; set; }

CatHistory 类如下所示(DogHistory 遵循相同的方案):

public class CatHistory : HistoricalEntity
{
  public int CatId { get; set; }

  public virtual Cat Cat{ get; set; }
}

我的目标是当一个对象被保存时,我想在适当的历史表中插入一条记录。使用反射时,我无法克服类型差异。我目前的尝试如下,我似乎被困在 //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);
          }
        }

最佳答案

你可以使用 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);
}

关于c# - 在 SaveChanges 重写中实现历史跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47188375/

相关文章:

c# - 使用 KeyWord + Lambda 表达式

c# - 获取 HTMLTable C# 的 InnerHtml

javascript - 在 C# 中的按钮 OnClick 事件之间调用 javascript

c# 和 SMO - 获取消息输出,例如 "Table already exists"以进行日志记录

c# - 如何改进这个 EF 查询?

c# - 这是如何运作的? LINQ to Entities 触发程序集加载?

c# - DDD 与 EF : Collection of Value objects

Java:检查一个类是否存在,如果存在则调用特定的方法

java - 用于关闭 JDBC 对象的通用助手

.net - 使用反射获取父类的名称