问题描述
我目前正在使用最新版本的实体框架的一个项目,我所遇到的我似乎无法来解决的问题。
当谈到更新现有的对象,我可以相当容易地更新对象属性确定,直到它是另一个类的引用属性。
在下面的例子中,我有一个名为Foo类,其中存储的各种属性,与其他班级的这些是实例2
公共类Foo
{
公众诠释标识{搞定;组;}
公共字符串名称{;组;}
公共SubFoo SubFoo {搞定;组}
公共AnotherSubFoo AnotherSubFoo {搞定;组}
}
当我用下面的编辑方法,我传递的对象我想更新,我可以设法让名称正确更新,但我还没有设法找到在其中得到SubFoo的属性的方法改变。例如,如果SubFoo类有名称的属性,并且这已被改变,是我的DB和newFoo之间不同,它不进行更新。
公共富编辑(富newFoo)
{ VAR dbFoo = context.Foo
.INCLUDE(X => x.SubFoo)
.INCLUDE(X => x.AnotherSubFoo)
。单(C => c.Id == newFoo.Id); VAR进入= context.Entry<富>(dbFoo);
entry.OriginalValues.SetValues(dbFoo);
entry.CurrentValues.SetValues(newFoo); context.SaveChanges(); 返回newFoo;
}
任何帮助或指针将大大AP preciated。
更新:
基于Slauma评论我修改我的方法
公共富编辑(富newFoo)
{ VAR dbFoo = context.Foo
.INCLUDE(X => x.SubFoo)
.INCLUDE(X => x.AnotherSubFoo)
。单(C => c.Id == newFoo.Id); context.Entry(dbFoo).CurrentValues.SetValues(newFoo);
context.Entry(dbFoo.SubFoo).CurrentValues.SetValues(newFoo.SubFoo); context.SaveChanges(); 返回newFoo;
}
在开始运行,我得到了错误
To try and get around this, I added code to try to attach the newFoo subclasses to the context, but this through an error saying that the ObjectManager already had an entity the same
CurrentValues.SetValues
only updates scalar properties but no related entities, so you must do the same for each related entity:
public Foo Edit(Foo newFoo)
{
var dbFoo = context.Foo
.Include(x => x.SubFoo)
.Include(x => x.AnotherSubFoo)
.Single(c => c.Id == newFoo.Id);
context.Entry(dbFoo).CurrentValues.SetValues(newFoo);
context.Entry(dbFoo.SubFoo).CurrentValues.SetValues(newFoo.SubFoo);
context.Entry(dbFoo.AnotherSubFoo).CurrentValues.SetValues(newFoo.AnotherSubFoo);
context.SaveChanges();
return newFoo;
}
If the relationship could have been removed altogether or have been created you also need to handle those cases explicitly:
public Foo Edit(Foo newFoo)
{
var dbFoo = context.Foo
.Include(x => x.SubFoo)
.Include(x => x.AnotherSubFoo)
.Single(c => c.Id == newFoo.Id);
context.Entry(dbFoo).CurrentValues.SetValues(newFoo);
if (dbFoo.SubFoo != null)
{
if (newFoo.SubFoo != null)
{
if (dbFoo.SubFoo.Id == newFoo.SubFoo.Id)
// no relationship change, only scalar prop.
context.Entry(dbFoo.SubFoo).CurrentValues.SetValues(newFoo.SubFoo);
else
{
// Relationship change
// Attach assumes that newFoo.SubFoo is an existing entity
context.SubFoos.Attach(newFoo.SubFoo);
dbFoo.SubFoo = newFoo.SubFoo;
}
}
else // relationship has been removed
dbFoo.SubFoo = null;
}
else
{
if (newFoo.SubFoo != null) // relationship has been added
{
// Attach assumes that newFoo.SubFoo is an existing entity
context.SubFoos.Attach(newFoo.SubFoo);
dbFoo.SubFoo = newFoo.SubFoo;
}
// else -> old and new SubFoo is null -> nothing to do
}
// the same logic for AnotherSubFoo ...
context.SaveChanges();
return newFoo;
}
You eventually also need to set the state of the attached entities to Modified
if the relationship has been changed and the scalar properties as well.
Edit
If - according to your comment - Foo.SubFoo
is actually a collection and not only a reference you will need something like this to update the related entities:
public Foo Edit(Foo newFoo)
{
var dbFoo = context.Foo
.Include(x => x.SubFoo)
.Include(x => x.AnotherSubFoo)
.Single(c => c.Id == newFoo.Id);
// Update foo (works only for scalar properties)
context.Entry(dbFoo).CurrentValues.SetValues(newFoo);
// Delete subFoos from database that are not in the newFoo.SubFoo collection
foreach (var dbSubFoo in dbFoo.SubFoo.ToList())
if (!newFoo.SubFoo.Any(s => s.Id == dbSubFoo.Id))
context.SubFoos.Remove(dbSubFoo);
foreach (var newSubFoo in newFoo.SubFoo)
{
var dbSubFoo = dbFoo.SubFoo.SingleOrDefault(s => s.Id == newSubFoo.Id);
if (dbSubFoo != null)
// Update subFoos that are in the newFoo.SubFoo collection
context.Entry(dbSubFoo).CurrentValues.SetValues(newSubFoo);
else
// Insert subFoos into the database that are not
// in the dbFoo.subFoo collection
dbFoo.SubFoo.Add(newSubFoo);
}
// and the same for AnotherSubFoo...
db.SaveChanges();
return newFoo;
}
这篇关于实体框架,问题更新相关对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!