代码之家  ›  专栏  ›  技术社区  ›  coffeecop

从SaveChanges中拦截并重定向实体保存

  •  0
  • coffeecop  · 技术社区  · 8 年前

    我目前在数据库中有一个表,其结构如下:

    Orders
        OrderId int , --Primary Key
        CustomerId int,
        PartId int,
        OrderDate Date,
        Quantity int
    

    不幸的是,因为OrderId被设置为主键,而不是CustomerId、PartId和OrderDate的组合键,所以我们在数据库中有以下许多实例:

    OrderId | CustomerId | PartId | OrderDate  | Quantity
    1       | 23         | 45     | 2016-11-16 | 1
    2       | 23         | 45     | 2016-11-16 | 1
    3       | 23         | 45     | 2016-11-16 | 1
    4       | 26         | 30     | 2016-10-25 | 1
    5       | 26         | 30     | 2016-10-25 | 1
    

    而不是:

    OrderId | CustomerId | PartId | OrderDate  | Quantity
    1       | 23         | 45     | 2016-11-16 | 3
    4       | 26         | 30     | 2016-10-25 | 2
    

    由于法规/日志问题,我无权更新数据库,更新会破坏旧代码。然而,我已经说服了我的老板允许我更新实体,以对任何向前移动的数据实施这些约束。

    我的想法是超越 SaveChanges DbContext 因此,如果遗留代码尝试添加另一行,其中 CustomerId , PartId OrderDate 已存在,该保存被取消,并且 Quantity 增加现有行的列。到目前为止,我有以下内容,但不确定如何取消保存、更新现有行并强制从内部保存该行 保存更改 .

    public override int SaveChanges()
    {
    
        var PartAssemblyList = ChangeTracker.Entries()
                                .Where( x => x.Entity is Order &&
                                             x.State == EntityState.Added);
    
        foreach (var entity in PartAssemblyList)
        {
            if (/*RowExists*/)
            {
                //Cancel Save (entity.State = EntityState.Unchanged)?
                //Update Quantity of Existing Row
                //Set existing row to save
            }
        }
    
        return base.SaveChanges();
    }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Fourat    8 年前

    Orders .然而,你为什么不把 SaveChanges() 呼叫并自己进行添加/更新作业?

    public void AddUpdateOrder(Order o)
    {
        using(var ctx = new YourDataModelContext())
        {
            if(ctx.Orders.Any(x => x.OrderId == o.OrderId && x.CustomerId == o.CustomerId && x.PartId == o.PartId && x.OrderDate == o.OrderDate))
            {
                var e = ctx.Orders.Where(x => x.OrderId == o.OrderId && x.CustomerId == o.CustomerId && x.PartId == o.PartId && x.OrderDate == o.OrderDate).FirstOrDefault();
                e.Quantity += 1;
                ctx.Entry(e).State = Modified; 
            }
            else
            {
                Order e = new Order() { OrderId = o.OrderId, CustomerId = o.CustomerId, PartId = o.PartId, OrderDate == o.OrderDate, Quantity = 1};
                ctx.Orders.Add(e);
            }
            ctx.SaveChanges();
        }
    }