Big*_*oe 4 entity-framework c#-4.0
我有一个实体,我检索如下,并与上下文分离:
ctx.Reviews.MergeOption = MergeOption.NoTracking;
Review review = (from r in ctx.Reviews.Include("ReviewNotes")
where r.ReviewID == reviewID
select r).First();
Run Code Online (Sandbox Code Playgroud)
然后我对关系中的对象进行了更改:
if (review.ReviewNotes.Count > 0)
{
ReviewNote r = review.ReviewNotes.ElementAt(0);
r.Note = "Ugg " + DateTimeOffset.Now.ToString();
r.CreatedDate = DateTimeOffset.Now;
}
Run Code Online (Sandbox Code Playgroud)
然后我附加了Object并循环子节点并在需要时更改它的实体状态.保存更改完成后,不会更新任何内容:
ctx.Reviews.Attach(review);
foreach (ReviewNote item in review.ReviewNotes)
{
if (item.ReviewNoteID == 0)
{
ctx.ObjectStateManager.ChangeObjectState(item, EntityState.Added);
}
else
{
key = ctx.CreateEntityKey("ReviewNotes", item);
if (ctx.TryGetObjectByKey(key, out original))
{
ctx.ApplyCurrentValues<ReviewNote>(key.EntitySetName, item);
}
}
}
ctx.ObjectStateManager.ChangeObjectState(review, EntityState.Modified);
ctx.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
因为你从MergeOption.NoTracking
你的实体开始Detached
.然后你修改并附加它们.您应该知道Attach会导致一个Unchanged EntityState - 也就是说,它附加到上下文后它没有改变.这样原始值和当前值都具有相同的值集:修改后的值.这就是为什么一旦你调用SaveChanges方法它就不会更新.
我认为你也误解了ApplyCurrentValues
方法的目的:
它将采用所提供的分离实体的值并使用其EntityKey在上下文中定位相同的实体.然后,它将使用分离实体的属性值替换附加实体的当前标量值.
在您已经附加分离实体的情况下,您实际上不需要调用它,而是需要将ReviewNote
实体的状态更改为Modified,以便EF对您的数据存储执行适当的更新方法:
ctx.Reviews.Attach(review);
foreach (ReviewNote item in review.ReviewNotes) {
if (item.ReviewNoteID == 0) {
ctx.ObjectStateManager.ChangeObjectState(item, EntityState.Added);
}
else {
key = ctx.CreateEntityKey("ReviewNotes", item);
if (ctx.TryGetObjectByKey(key, out original)) {
// ctx.ApplyCurrentValues(key.EntitySetName, item);
ctx.ObjectStateManager.ChangeObjectState(item, EntityState.Modified);
}
}
}
ctx.ObjectStateManager.ChangeObjectState(review, EntityState.Modified);
ctx.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
编辑:
另一种方法是运行相同的查询并将ReviewNote对象放入内存,然后在每个对象上调用ApplyCurrentValues,以便只有具有已更改属性的对象才会进入修改状态:
// This time you don't need to attach:
//ctx.Reviews.Attach(review);
// Make sure you have them in the memory:
Review review2 = (from r in ctx.Reviews.Include("ReviewNotes")
where r.ReviewID == reviewID
select r).First();
foreach (ReviewNote item in review.ReviewNotes) {
if (item.ReviewNoteID == 0) {
ctx.ReviewNotes.AddObject(item);
}
else {
key = ctx.CreateEntityKey("ReviewNotes", item);
if (ctx.TryGetObjectByKey(key, out original)) {
// Note that the item is a detached object now:
ctx.ApplyCurrentValues(key.EntitySetName, item);
}
}
}
ctx.ObjectStateManager.ChangeObjectState(review, EntityState.Modified);
ctx.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
另请注意,ApplyCurrentValues仅适用于单个实体上的标量属性,并且不会考虑导航属性,否则我们只需在Review对象上调用它一次,而无需进入循环以将其应用于每个ReviewNote .
归档时间: |
|
查看次数: |
8280 次 |
最近记录: |