0

i'm sorry if this question has already been asked, but i'm in trouble with my method of updating collection in Entity Framework.

Let me explain the situation : - I have for example one model CUSTOMER with some properties and a collection of ORDERS (for example). - Let's imagine we have an admin page on wich we can edit all the ORDERS for a customer, and when we submit the form, it will send us back the object CUSTOMERS with updated ORDERS (some added, some updated and some deleted).

For the moment i use something like this in order to compare old collection and new collection and determine which object i need to delete/update/add

 var toRemove = new List<ORDERS>();
        var toAdd = new List<ORDERS>();
        foreach (
            var order in
                oldList.Where(
                    order =>
                    newList.FirstOrDefault(t => t.link_id == order.link_id) == null))
        {
            toRemove.Add(order);
        }
        foreach (
            var order in
                newList.Where(
                    order =>
                    oldList.FirstOrDefault(t => t.link_id == order.link_id) == null))
        {
            toAdd.Add(order);
        }
        foreach (var ORDERSe in toRemove)
        {
            bdd.ORDERS.Remove(ORDERSe);
        }
        foreach (var ORDERSe in toAdd)
        {
            ORDERSe.pjt_id = project_id;
            bdd.ORDERS.Add(ORDERSe);
        }

        foreach (
            var order in
                newList.Where(
                    order =>
                    oldList.FirstOrDefault(t => t.link_id == order.link_id) != null))
        {
            var child = oldList.FirstOrDefault(t => t.link_id == order.link_id);
            bdd.Entry(child).CurrentValues.SetValues(order);
        }

But i'm unconfortable with this, because in my mind, entity framework should be able to do the work for me !

I was hoping something like :

customer.orders = newOrders;

Did i missed anything about entity framework or ? Because when i do this, it just duplicate my orders. Thanks in advance for your answer.

4

2 回答 2

1

您当然可以使用 .Except() 和 .Intersect() 使其更清洁,但概念并没有真正改变,AFAIK 您仍然必须单独删除、更新和添加循环中的条目......

var oldList = new List<ORDERS>();
var newList= new List<ORDERS>();

var IdsToRemove = oldList.Select(t => t.link_id).Except(newList.Select(t => t.link_id));
var IdsToAdd = newList.Select(t => t.link_id).Except(oldList.Select(t => t.link_id));
var IdsToUpdate =  newList.Select(t => t.link_id).Intersect(oldList.Select(t => t.link_id));

//remove
bdd.orders.where(x => IdsToRemove.Contains(x.link_id)).ForEach(x => bdd.Remove(x));
//add
foreach(var order in newList.Where(x -> IdsToAdd.Contains(x.link_id))
{
   bdd.Orders.Attach(order);
   bdd.Entries(order).EntityState = EntityState.Added;
}
//update
foreach(var order in newList.Where(x -> IdsToUpdate .Contains(x.link_id))
{
   bdd.Orders.Attach(order);
   bdd.Entries(order).EntityState = EntityState.Modified;
}

bdd.SaveChanges();
于 2013-09-10T16:41:39.713 回答
0

但我对此并不满意,因为在我看来,实体框架应该能够为我完成这项工作!

事实上,EF 为您完成了这项工作。使用数据上下文 SaveChanges 方法 EF 应该能够一次保存所有更改:

DbContext.SaveChanges()

为了您的方便,您仍然可以覆盖此方法。在内部你应该使用这样的东西:

public override int SaveChanges()
{
   var changeSet = ChangeTracker.Entries<IAuditable>();

   if (changeSet != null)
   {
      foreach (var entry in changeSet.Where(c => c.State != EntityState.Unchanged))
      {
          entry.Entity.ModifiedDate = DateProvider.GetCurrentDate();
          entry.Entity.ModifiedBy = UserName;
      }
   }
   return base.SaveChanges();

}

于 2013-09-10T16:12:04.793 回答