简体   繁体   中英

Object versioning in C#

I have some classes in an Entity framework model, as the example below:

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; }
}

The order, and its related items, can be edited by adding new items/item addons or deleting some of them, after saving and for more than one time, but I want to save every version of the order object, and to fetch the difference between each version. what's the best practice to do that?

There isn't a natural key for your Order entity. With a meaningful OrderNumber property, you could use it combined with OrderOn as a versioned natural key.

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; }
}

You'll want to override the modelBuilder so that EF creates the unique key constraint in the database:

[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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM