实体框架更新多行
Posted
技术标签:
【中文标题】实体框架更新多行【英文标题】:Entity Framework Update Multiple Rows 【发布时间】:2014-03-31 12:26:12 【问题描述】:我有一个表单,允许用户对小部件进行更改,然后输入将应用相同更改的其他小部件列表。使用实体框架,我有以下工作,但它很慢而且似乎效率不高:
//objectToSave: widgets - array of widgets to save changes to
// pcram - changes to apply to each widget
public HttpResponseMessage PutPcram(ObjectToSave objectToSave)
if (!ModelState.IsValid)
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
//loop through the widgets we want to save changes to
for (var i = 0; i < objectToSave.widgets.Length; i++)
var e = db.PcramChanges.Find(objectToSave.widgets[i]);
var excluded = new[] "widgetID" ;
var x = db.Entry(e);
foreach (var name in x.CurrentValues.PropertyNames.Except(excluded))
x.Property(name).IsModified = true;
db.Entry(e).Property(name).CurrentValue = db.Entry(objectToSave.pcram).Property(name).CurrentValue;
try
db.SaveChanges();
catch (DbUpdateConcurrencyException ex)
return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
return Request.CreateResponse(HttpStatusCode.OK);
我基本上想将对所选小部件所做的更改保存到多个小部件,这是我能想到的排除主键“widgetID”的唯一方法。有什么改进的建议吗?
【问题讨论】:
【参考方案1】:我知道我迟到了,但是ForEach
呢?
objectToSave.widgets.ForEach(o => o.Prop1 = Val1, o.Prop2 = Val2 );
Db.ObjectContext.SaveChanges();
【讨论】:
【参考方案2】:Entity Framework
(至少到 EF5.0,可能在 EF6.0 的情况有所改变)无法执行批量更新。它为每个行更新生成单个查询。我可以建议看看EntityFramework.Extended library,它有扩展方法,允许执行批量更新和批量删除。
【讨论】:
【参考方案3】:EF 的更改跟踪引擎足够慢,并且会在每次属性更改时触发。
如果这是您的原因,请尝试将循环包装在
db.Configuration.AutoDetectChangesEnabled = false;
for (int i = 0; i < objectToSave.widgets.Length; i++)
// here is the logic
Db.ObjectContext.DetectChanges();
Db.Configuration.AutoDetectChangesEnabled = true;
【讨论】:
【参考方案4】:您可以尝试在不同的线程中执行多个操作,这总是更快。尝试抓取一组小部件并在一个线程中进行更改。另一个线程中的另一组小部件,依此类推。组越小(线程越多),它可能会更快,直到您的电脑说相反。请参阅here,这是一种方法。
【讨论】:
以上是关于实体框架更新多行的主要内容,如果未能解决你的问题,请参考以下文章