【问题标题】:Object versioning in C#C# 中的对象版本控制
【发布时间】:2014-01-02 16:34:34
【问题描述】:
我在实体框架模型中有一些类,如下例所示:
public class Order
{
public int Id { get; set; }
public DateTime DateTime{ get; set; }
public decimal TotalPrice { get; set; }
public virtual ICollection<OrderItem> Items { get; set; }
}
public class OrderItem
{
public int Id { get; set; }
public Product Product { get; set; }
public int Quantity { get; set; }
public decimal TotalPrice { get; set; }
public virtual ICollection<AddOn> AddOns { get; set; }
}
public class Product
{
public int Id { get; set;}
public string Name { get; set; }
public decimal Price { get; set; }
}
public class AddOn
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
在保存多次后,可以通过添加新项目/项目插件或删除其中一些来编辑订单及其相关项目,但我想保存订单对象的每个版本,并获取每个版本之间的差异。这样做的最佳做法是什么?
【问题讨论】:
标签:
c#
entity-framework
object
versioning
【解决方案1】:
Order 实体没有自然键。使用有意义的 OrderNumber 属性,您可以将其与 OrderOn 结合使用作为版本化的自然键。
public class Order
{
public int Id { get; set; }
public string OrderNumber { get; set; } // <- add this property
public DateTime OrderedOn { get; set; } // <- change this property name
// OrderNumber, OrderedOn is a unique key
public decimal TotalPrice { get; set; }
public virtual ICollection<OrderItem> Items { get; set; }
}
您需要覆盖模型构建器,以便 EF 在数据库中创建唯一键约束:
[SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "IDisposable implemented as intended.")]
public class OrderingDbContext : DbContext, IDisposable
{
private readonly IDatabaseInitializer<OrderingDbContext> _initializer;
public OrderingDbContext(DbConnection connection) : this(connection, new NullDatabaseInitializer<OrderingDbContext>()) { }
public OrderingDbContext(DbConnection connection,
IDatabaseInitializer<OrderingDbContext> initializer)
: base(connection, false)
{
_initializer = initializer;
}
public DbSet<Order> Orders { get; set; }
// ...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(_initializer);
modelBuilder.Entity<Order>()
.HasKey(o => new { o.OrderNumber, o.OrderedOn });
base.OnModelCreating(modelBuilder);
}
#region IDisposable
private bool _disposed;
public new void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private new void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
base.Dispose();
_disposed = true;
}
~OrderingDbContext()
{
Dispose(false);
}
#endregion
}