【发布时间】:2014-05-21 06:19:56
【问题描述】:
我正在使用 EF 6.1 Code First 并希望通过使用如下模型(简化)来跟踪历史数据:
public class Customer : IHistoryData<CustomerData>
{
public Guid ID { get; set; }
public virtual ISet<CustomerData> Versions { get; set; }
}
public class CustomerData : HistoricalData
{
public string Name { get; set; }
}
public interface IHistoryData<T> where T : HistoricalData
{
ISet<T> Versions { get; set; }
}
public class HistoricalData
{
public int VersionID { get; set; }
public Guid ParentID { get; set; }
public DateTime ValidFrom { get; set; }
public DateTime? ValidUntil { get; set; }
}
它们以下列方式连接到 DbContext 中:
modelBuilder.Ignore<HistoricalData>();
modelBuilder.Entity<Customer>().ToTable("Customers").HasMany(c => c.Versions).WithRequired().HasForeignKey(cd => cd.ParentID);
modelBuilder.Entity<CustomerData>().Map(m => m.ToTable("CustomerData")).HasKey(cd => new { cd.VersionID, cd.ParentID });
现在要跟踪不同的客户版本,我需要对 CustomerData 的更改执行插入而不是更新。为此,我加入了SaveChangesAsync() 的DbContext:
public override Task<int> SaveChangesAsync()
{
foreach (var entry in ChangeTracker.Entries<HistoricalData>().Where(e => e.State == EntityState.Modified))
{
InsertInsteadOfUpdate(entry);
}
return base.SaveChangesAsync();
}
现在我不确定如何实现InsertInsteadOfUpdate(),这是我目前的做法:
private void InsertInsteadOfUpdate<T>(DbEntityEntry<T> oldEntry) where T : HistoricalData
{
// Get a copy of the modified data
var newEntry = ???
// Modified entry has ended
var originalValues = oldEntry.OriginalValues;
originalValues["ValidUntil"] = DateTime.Now;
oldEntry.CurrentValues.SetValues(originalValues);
// New entry has started
newEntry.ValidFrom = DateTime.Now;
Set<T>().Add(newEntry);
}
但是,我不知道如何获得DbEntityEntry<CustomerData> 的新副本/克隆。而且因为我都需要修改“旧”条目(设置ValidUntil)并插入一个新条目,所以我需要两个不同的条目。
我会怎么做呢?还是我完全走错了路?
【问题讨论】:
标签: c# entity-framework ef-code-first change-tracking entity-framework-6.1