How to save changes to related table in MVC 5 and EF 6 - Entity Framework Master-Detail

后端 未结 1 1301
猫巷女王i
猫巷女王i 2020-12-21 21:55

I have two tables, Promotion and PromotionLine, with a foreign key defined as PromotionLine.PromoID = Promotion.ID

PromotionLines are associated with the Promotion m

相关标签:
1条回答
  • 2020-12-21 22:27

    This is not a trivial task. You need to update your object graph. In other word you need a Master-Detail update.

    To keep the answer simple I suppose I have an Order entity that have OrderDetails property that is a List<OrderDetail>.You should pay attention when editing:

    • There are some OrderDetail that have been added to OrderDetails and the main sign of them is having Id property equal to 0.
    • Some OrderDetail have been removed and no longer exist in OrderDetails
    • Some OrderDetail have been changed.

    When updating the Order you should update the Order itself and also apply above changes.

    Steps

    Here are steps:

    1. Get original order from database.
    2. Update the value of original order using edited order.
    3. Find list of added items (Id of added items is 0).
    4. Find list of removed items (list of order details of original order where id of original order details is not between ids of order details of edited order).
    5. Find list of edited items (list of order details of original order where id of original order details is between ids of order details of edited order).
    6. Use a loop over deleted items list and set state of them to removed.
    7. Use a loop over edited items list and update value of original order details that have been loaded in context.
    8. Use a loop over added items list and set state of them to added.
    9. Set the state of original order to modified.
    10. Save context changes.

    Code

    Here is the code:

    public void Update(Order editedOrder)
    {
        using(var context = new YourDbContext())
        {   
            //Get original order from database.
            var originalOrder = context.Orders.Including("OrderDetails")
                .Where(x => x.OrderId == editedOrder.OrderId).FirstOrDefault();
    
            //Update the value of original order using edited order.
            context.Entry(originalOrder).CurrentValues.SetValues(editedOrder);
    
            //Find list of added items (Id of added items is 0).
            var addedList = editedOrder.OrderDetails
                .Where(y => y.OrderDetailId == 0).ToList();
    
            //Find list of removed items.
            var deletedList = originalOrder.OrderDetails
                .Where
                (
                    x =>!editedOrder.OrderDetails.Select(y => y.OrderDetailId)
                            .Contains(x.OrderDetailId)
                )
                .ToList();
    
            //Find list of edited items.
            var editedList = editedOrder.OrderDetails
                .Where
                (
                    y => originalOrder.OrderDetails.Select(z => z.OrderDetailId)
                             .Contains(y.OrderDetailId)
                )
                .ToList();
    
            //Use a loop over deleted items list and set state of them to removed.
            deletedList.ForEach(deletedDetail =>
            {
                originalOrder.OrderDetails.Remove(deletedDetail);
                context.Entry(editedOrder).State = EntityState.Deleted;
            });
    
            //Use a loop over edited items list 
            //and update value of original order details  that have been loaded in context.
            editedList.ForEach(editedDetail =>
            {
                var originalOrderDetail = originalOrder.OrderDetails
                    .Where(x => x.OrderDetailId == editedDetail.OrderDetailId)
                    .FirstOrDefault();
               context.Entry(originalOrderDetail).CurrentValues.SetValues(editedDetail);
            });
    
            //Use a loop over added items list and set state of them to added.
            addedList.ForEach(addedDetail =>
            {
                originalOrder.OrderDetails.Add(addedDetail);
            });
    
            //Set the state of original order to modified.
            context.Entry(oroginalOrder).State = System.Data.Entity.EntityState.Modified;
    
            //Save context changes.
            context.SaveChanges();
        }
    }
    
    0 讨论(0)
提交回复
热议问题