C#,Entity Framework,如何同时更新(删除、添加、编辑)多行?
C#, Entity Framework, How to Update(delete, add, edit) multiple rows at same time?
有时,我们会根据客户的要求或根据库存数量通过添加、删除和编辑订单来更改订单详细信息。
所以现在想要获取一些列表并进行更新,包括删除、编辑、添加行,然后保存在数据库中
作为 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 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();
}
更新多行是否正确?
除了进行所有更改然后调用 SaveChanges 之外,没有“最有效”的方法。 Ef 将在此基础上发出大量 SQL 语句(每个操作一个)。
有一种最有效的方法,因为无法更改 Ef 的工作方式,而且只有一种 Ef 进行更新的方式。它们不会同时发生。时期。当您调用 SaveChanges 时,它们会在一个事务中一个接一个地发生。
如另一个答案所述...EF 将为检测到的每个更改(即更新、插入、删除)创建单独的语句,并在单个事务中提交它们。完成工作但可能非常“健谈”。好处是您无需担心它是如何完成的细节。只需修改数据对象并调用 SaveChanges 即可。
如果您可以考虑不使用 EF 进行此类更新...我们执行此类更新的一种方法是创建 System.Data.DataTable 并将其用作 table-valued 参数存储过程(如果您的数据存储支持它)。
Meta-code:
var dt = new DataTable();
var newRow = dt.NewRow();
newRow["column1"] = newdata;
dt.Rows.Add(newRow);
然后只需使用 dt
作为您的输入参数,让存储过程确定 insert/update/delete 操作。
如果您想从 Entity Framework 中的表中添加/删除/更新行,您必须添加/删除/更新 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);
}
要删除,您首先必须获取完整的订单
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 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();
有时,我们会根据客户的要求或根据库存数量通过添加、删除和编辑订单来更改订单详细信息。
所以现在想要获取一些列表并进行更新,包括删除、编辑、添加行,然后保存在数据库中
作为 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 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();
}
更新多行是否正确?
除了进行所有更改然后调用 SaveChanges 之外,没有“最有效”的方法。 Ef 将在此基础上发出大量 SQL 语句(每个操作一个)。
有一种最有效的方法,因为无法更改 Ef 的工作方式,而且只有一种 Ef 进行更新的方式。它们不会同时发生。时期。当您调用 SaveChanges 时,它们会在一个事务中一个接一个地发生。
如另一个答案所述...EF 将为检测到的每个更改(即更新、插入、删除)创建单独的语句,并在单个事务中提交它们。完成工作但可能非常“健谈”。好处是您无需担心它是如何完成的细节。只需修改数据对象并调用 SaveChanges 即可。
如果您可以考虑不使用 EF 进行此类更新...我们执行此类更新的一种方法是创建 System.Data.DataTable 并将其用作 table-valued 参数存储过程(如果您的数据存储支持它)。
Meta-code:
var dt = new DataTable();
var newRow = dt.NewRow();
newRow["column1"] = newdata;
dt.Rows.Add(newRow);
然后只需使用 dt
作为您的输入参数,让存储过程确定 insert/update/delete 操作。
如果您想从 Entity Framework 中的表中添加/删除/更新行,您必须添加/删除/更新 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);
}
要删除,您首先必须获取完整的订单
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 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();