我从数据库中提取了一堆时间表条目,并使用它们来创建发票。保存发票并拥有ID后,我想用发票ID更新时间表条目。有没有办法批量更新实体而不一次加载一个实体?
void SaveInvoice(Invoice invoice, int[] timeEntryIds) {
context.Invoices.Add(invoice);
context.SaveChanges();
// Is there anything like?
context.TimeEntries
.Where(te => timeEntryIds.Contains(te.Id))
.Update(te => te.InvoiceId = invoice.Id);
}
答案 0 :(得分:6)
免责声明:我是该项目的所有者Entity Framework Plus
我们的图书馆有一个批量更新功能,我相信你正在寻找
此功能支持EF Core
// Is there anything like? YES!!!
context.TimeEntries
.Where(te => timeEntryIds.Contains(te.Id))
.Update(te => new TimeEntry() { InvoiceId = invoice.Id });
答案 1 :(得分:2)
如果TimeEntry
与Invoice
有关联(检查导航属性),您可以执行以下操作:
var timeEntries = context.TimeEntries.Where(t => timeEntryIds.Contains(te.Id)).ToArray();
foreach(var timeEntry in timeEntries)
invoice.TimeEntries.Add(timeEntry);
context.Invoices.Add(invoice);
//save the entire context and takes care of the ids
context.SaveChanges();
答案 2 :(得分:2)
您是否经历过简化语法的表现?
我建议使用直接SQL查询,
string query = "Update TimeEntries Set InvoiceId = <invoiceId> Where Id in (comma separated ids)";
context.Database.ExecuteSqlCommandAsync(query);
对于以逗号分隔的ID,您可以执行string.Join(',', timeEntryIds)
这取决于你真正需要的是什么。如果你想使用Linq,那么你需要遍历每个对象。
答案 3 :(得分:0)
在实体框架核心中,您可以使用update range method。您可以看到一些示例用法here。
using (var context = new YourContext())
{
context.UpdateRange(yourModifiedEntities);
// or the followings are also valid
//context.UpdateRange(yourModifiedEntity1, yourModifiedEntity2, yourModifiedEntity3);
//context.YourEntity.UpdateRange(yourModifiedEntities);
//context.YourEntity.UpdateRange(yourModifiedEntity1, yourModifiedEntity2,yourModifiedEntity3);
context.SaveChanges();
}
答案 4 :(得分:0)
免责声明:我是项目ELinq
的维护者该库允许用C#编写SQL,实体定义取自EF Core映射。尽可能将收集方法映射到相应的SQL构造(包括Contains
)。
因此所需的查询将类似于以下内容:
var invoiceId = invoice.Id;
context.Database.Query((TimeEntry te) => {
UPDATE(te).SET(() => {
te.InvoiceId = invoiceId;
});
WHERE(timeEntryIds.Contains(te.Id));
});