我有一个允许用户对窗口小部件进行更改的表单,然后输入将应用相同更改的其他窗口小部件列表。使用实体框架,我有以下工作,但它很慢,看起来效率不高:
//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”,这是主键。关于如何改进这个的任何建议?
答案 0 :(得分:1)
我知道我迟到了,但ForEach
呢?
objectToSave.widgets.ForEach(o => { o.Prop1 = Val1, o.Prop2 = Val2 });
Db.ObjectContext.SaveChanges();
答案 1 :(得分:0)
Entity Framework
(至少EF5.0,可能在EF6.0中,情况已经改变)无法执行批量更新。它为每个行更新生成单个查询。我建议您查看EntityFramework.Extended库,它具有扩展方法,允许执行批量更新和批量删除。
答案 2 :(得分:0)
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;
答案 3 :(得分:0)
您可以尝试在不同的线程中执行多个操作,这总是更快。尝试抓取一组小部件并在一个线程中进行更改。另一组小部件在另一个线程中等等。组越小(线程越多),它可能会更快,直到你的电脑说相反。请参阅here,这是一种方法。