我正在为实体框架代码和合并而苦苦挣扎。我有一个带有通用存储库的MVC控制器。一个视图模型被张贴出来,我把它转换成EF知道的类型
var converted = AutoMapper.Mapper.Map<RoutineViewModel, Routine>(result);
_routineRepository.Update(converted);在存储库中,我有:
/*
Routines.Attach(item);
ChangeTracker.Entries<Routine>().Single(x => x.Entity.Id == item.Id).State = EntityState.Modified;*/
var match = Routines.Single(x => x.Id == item.Id);
var entity = Entry(match);
entity.CurrentValues.SetValues(item);我注释掉了第一个比特,因为它抛出了一个关于已经跟踪实体的错误,即使像这样的检查:
if (ChangeTracker.Entries<Routine>().Count(x => x.Entity.Id == item.Id) != 0)返回false
我遇到的问题是,这个例程对象有一个步骤的ICollection属性。当我将被跟踪实体的值设置为与poco的值匹配时,ICollection更改不会向下传播。环顾这个站点,看起来有一些看起来很糟糕的递归调用。这是真的吗?还是我漏掉了什么?
有什么简单的方法可以说,这是源对象(未跟踪的),将它的所有内容复制到跟踪的对象中吗?
为了清楚起见,我不认为首先获取对象并更新对象上的属性应该在存储库之外完成。这似乎不仅迫使您跨域边界传递数据模型,而且似乎不是等效的SQL like语句是(update x,y where id = 1),to (insert into temp table where id = 1,for reach row in temp table,update x.....现在,对于表中的每一行,更新table x= tempx,其中id = 1)
编辑--所以问题出在setValues不是一个递归调用。例程对象有两个简单的属性(id和name)和一个复杂的属性(ICollection )。如果传入的项的名称发生了更改,并且某些步骤也发生了更改,则setValues会选择名称更改,但不会应用于子项。有没有其他方法可以做到这一点?我不得不用手卷起这个功能,这对我来说似乎有点奇怪。
发布于 2012-02-24 14:47:20
据我所知,您正在创建您的实体,填充属性,然后将其附加到DB。这与EF有些不同。
如果要附加已在数据库中但未被跟踪的对象,可以使用attach,但只有在attach调用之后所做的更改才会被记录并提交到数据库。如果要使用attach,请确保在调用该方法后进行更改。
此外,EF仅允许您附加当前不在对象图中的对象。因此,如果您尝试将同一对象附加两次(或使用相同的关键点),则会出现与您看到的错误类似的错误。
https://stackoverflow.com/questions/9426425
复制相似问题