C#,实体框架,如何同时更新(删除、添加、编辑)多行?

C#,实体框架,如何同时更新(删除、添加、编辑)多行?,c#,.net,linq,entity-framework-6,C#,.net,Linq,Entity Framework 6,有时,我们希望根据客户的要求或根据库存数量,通过添加、删除和编辑订单来更改订单详细信息 所以现在需要一些列表和更新,包括删除、编辑、添加行,然后保存到数据库中 作为C#,EntityFramework的最佳有效方式是什么 public class OrderDetail { public int Id { get; set; } public int OrderId {get; set; } public int Qty{ get; set; } public string It

有时,我们希望根据客户的要求或根据库存数量,通过添加、删除和编辑订单来更改订单详细信息

所以现在需要一些列表和更新,包括删除、编辑、添加行,然后保存到数据库中

作为C#,EntityFramework的最佳有效方式是什么

public class OrderDetail
{
  public int Id { get; set; }
  public int OrderId {get; set; }
  public int Qty{ get; set; }
  public string ItemName { get; set; }
}

/// Dummy db, OrderDetail Table
{
 {1, 1000, 24,"A"},
 {2, 1000, 12,"B"}
}


public void Update()
{
  using(var db = new xxEntities())
  {
    // Get All orders, OrderId==1000, total 2rows
    List<OrderDetails> list = db.OrderDetails.Where(x=> x.OrderId==1000).ToList();
    
    // remove some row or rows
    var temp1 = list.First(x=> x.Id==1);
    list.Remove(temp);

    // edit some row or rows
    var temp2 = list.First(x=> x.Id==2);
    temp2.Qty=100;
    
    // add some row or rows
    list.Add(new OrderDetail{ Id=3, OrderId=1000, Qty=2, ItemName="C"});
    list.Add(new OrderDetail{ Id=4, OrderId=1000, Qty=2, ItemName="D"});

    // Apply all changes
   db.SaveChanges();
  }
}

public类OrderDetail
{
公共int Id{get;set;}
公共int-OrderId{get;set;}
公共整数数量{get;set;}
公共字符串ItemName{get;set;}
}
///虚拟数据库,OrderDetail表
{
{1,1000,24,“A”},
{2,1000,12,“B”}
}
公共无效更新()
{
使用(var db=new xxEntities())
{
//获取所有订单,订单ID==1000,总共2行
List List=db.OrderDetails.Where(x=>x.OrderId==1000).ToList();
//删除一些行
var temp1=list.First(x=>x.Id==1);
列表。删除(临时);
//编辑一些行
var temp2=list.First(x=>x.Id==2);
temp2.数量=100;
//添加一些行
添加(新订单详细信息{Id=3,订单Id=1000,数量=2,ItemName=“C”});
添加(新订单详细信息{Id=4,订单Id=1000,数量=2,ItemName=“D”});
//应用所有更改
db.SaveChanges();
}
}

补充问题

public void UpdateOrder(int orderId, List<OrderDetail> newOrders)
{
  var result = db.OrderDetails.Where(x=>x.OrderId==orderId).ToList();
  result = newOrders;
 
 // it does not work
 //db.OrderDetails.Update(result);

 db.OrderDetails.RemoveRange(result);
 db.OrderDetails.AddRange(newOrders);

 db.SaveChange();
}
public void UpdateOrder(int orderId,List newOrders)
{
var result=db.OrderDetails.Where(x=>x.OrderId==OrderId.ToList();
结果=新订单;
//它不起作用
//db.OrderDetails.Update(结果);
db.OrderDetails.RemoveRange(结果);
db.OrderDetails.AddRange(新订单);
db.SaveChange();
}
更新多行是正确的方法吗?

除了进行所有更改然后调用SaveChanges之外,没有“最有效”的方法。在此基础上,Ef将发出大量SQL语句(每个操作一条)


这是最有效的方法,因为没有办法改变Ef的工作方式,只有一种方法Ef进行更新。它们不会同时发生。时期它们发生在一个事务中,一个接一个,当您调用SaveChanges时。

如另一个答案中所述。。。EF将为检测到的每个更改(即更新、插入、删除)创建单独的语句,并在单个事务中提交它们。完成任务,但可能非常“健谈”。好处是你不需要担心如何完成的细节。只需修改数据对象并调用SaveChanges就很容易了

如果您可以考虑不使用EF进行更新,例如…我们进行此类更新的一种方法是创建System.Data.DataTable,并将其作为表值参数使用到存储过程中(如果您的数据存储支持)

元代码:

var dt = new DataTable();
var newRow = dt.NewRow();
newRow["column1"] = newdata; 
dt.Rows.Add(newRow);

然后,只需使用
dt
作为输入参数,并让存储的过程确定插入/更新/删除操作。

如果要在实体框架中的表中添加/删除/更新行,则必须在
DbSet
中添加/删除/更新项,而不是在获取的数据中

using (var dbContext = new OrderContext())
{
    // Add one Order
    Order orderToAdd = new Order
    {
        // fill required properties; don't fill primary key
    }

    var addedOrder = dbContext.Orders.Add(orderToAdd);
    // note: addedOrder has no Id yet.

    // Add several Orders
    IEnumerable<Order> orders = ...
    dbContext.Orders.AddRange(orders);

    dbContext.SaveChanges();
    // now they've got their id:
    Debug.Assert(addedOrder.Id != 0);
    Debug.Assert(orders.All(order => order.Id != 0);
}
使用(var dbContext=new OrderContext())
{
//添加一个订单
订单添加=新订单
{
//填写必需的属性;不填写主键
}
var addedOrder=dbContext.Orders.Add(orderToAdd);
//注意:加法器还没有Id。
//添加多个订单
IEnumerable orders=。。。
dbContext.Orders.AddRange(订单);
dbContext.SaveChanges();
//现在他们有了身份证:
Assert(addedOrder.Id!=0);
Assert(orders.All(order=>order.Id!=0);
}
要删除,您首先必须获取完整的订单

int orderIdToDelete = ...
using (var dbContext = new OrderContext())
{
    Order orderToDelete = dbContext.Orders.Find(orderIdToDelete);
    dbContext.Orders.Remove(orderToDelete);

    var ordersToDelete = dbContext.Orders
        .Where(order => order.Date.Year < 2000)
        .ToList();
    dbContext.Orders.RemoveRange(ordersToDelete);

    // the orders are not deleted yet.
    dbContext.SaveChanges();
}
int-orderIdToDelete=。。。
使用(var dbContext=new OrderContext())
{
Order orderToDelete=dbContext.Orders.Find(orderIdToDelete);
dbContext.Orders.Remove(orderToDelete);
var ordersToDelete=dbContext.Orders
.其中(订单=>order.Date.Year<2000)
.ToList();
dbContext.Orders.RemoveRange(ordersToDelete);
//订单尚未删除。
dbContext.SaveChanges();
}
要更新,首先必须获取以下值:

int orderIdToUpdate = ...
Order orderToUpdate = dbContext.Orders.Find(orderIdToUpdate);
orderToUpdate.Date = DateTime.Today;

var today = Datetime.Today;
var dateLimit = today.AddDays(-28);
var nonPaidOrders = dbContext.Orders
    .Where(order => !order.Paid && order.Date < dateLimit)
    .ToList();
foreach (var order in nonPaidOrders)
{
    this.SendReminder(order);
    order.ReminderDate = today;
}
dbContext.SaveChanges();
int-orderIdToUpdate=。。。
Order orderToUpdate=dbContext.Orders.Find(orderIdToUpdate);
orderToUpdate.Date=DateTime.Today;
var today=Datetime.today;
var dateLimit=今天。添加天数(-28);
var nonPaidOrders=dbContext.Orders
.Where(order=>!order.Paid&&order.Date
假设,通过添加、编辑、删除旧订单,旧订单有2行,新订单有5行。这就是我使用RemoveRange和AddRange的原因。