实体框架服务层更新POCO

3
我正在使用“服务层->存储库->实体框架(Code-First) w/POCO对象”方法,并且我在更新实体方面遇到了困难。
我使用AutoMapper将我的域对象映射到我的视图模型,这对于获取数据很有用,现在该如何将更改保存回数据库呢?
使用纯POCO对象,我认为没有任何形式的更改跟踪,所以我认为我唯一的选择是自己处理。你只需确保你的视图模型与你的域对象具有完全相同的属性吗?如果我只在视图模型上更改一个或两个字段,那么域对象中的其余字段不会被默认值覆盖吗?
那么,最好的方法是什么?
谢谢!
编辑
所以我遇到的问题是这样的,我们以一个简单的“客户”为例:
1)控制器有一个服务,“CustomerService”,它调用服务的“GetCustmoerByID”方法。
2)服务调用“CustomerRepository”并检索“Customer”对象。
3)控制器使用AutoMapper将“Customer”映射到“ViewModel”。
4)控制器将模型交给“View”。一切都很好!
现在,在视图中,您对客户进行了一些修改,并将其发送回控制器以将更改保存到数据库。
我假设此时对象已分离。那么,模型是否应该与“Customer”对象具有完全相同的属性?您是否必须为每个不想显示的项目创建隐藏字段,以便它们可以持久化回来?
如何处理将对象保存回数据库?如果您的视图/模型仅涉及对象的一些字段会发生什么?

如果你使用Automapper进行单向映射,为什么不能使用它进行双向映射呢? - stephen776
3个回答

5
如果你正在使用EF Code First,即DbContext API,则仍然具有由你的上下文类负责的更改跟踪。
在对对象进行更改之后,您只需要在上下文中调用SaveChanges(),这将将更改保存到数据库中。
编辑:
由于您使用AutoMapper创建了实体的“副本”,因此它不再附加到您的上下文中。
我猜你可以做类似于ASP.NET MVC(使用UpdateModel)的事情。您可以从上下文中获取原始实体,取您的ViewModel(其中可能包含更改的属性),并更新旧实体,手动修改属性或使用AutoMapper。然后使用context.SaveChanges()保存更改。
另一个解决方案是将模型实体作为ViewModel的一部分发送。这样,您将拥有附加到容器的实体,并且更改跟踪仍将起作用。
希望这能帮助您 :)

3
您说得很对,使用游离对象时,您需要负责通知上下文有关游离实体的更改。
基本方法就是将实体设置为已修改。这适用于标量和复杂属性,但不适用于导航属性(除了FK关系)-有关导航属性问题的进一步阅读,请查看此答案(它涉及EFv4和ObjectContext API,但使用DbContext API也存在相同的问题)。该方法的缺点是会修改DB中的所有字段。如果您只想修改单个字段,则仍需正确填写其他字段,否则数据库记录将损坏。
有一种方法可以明确定义哪些字段已更改。您将按属性而不是整个实体设置修改状态。这在通用方法上有点困难,但我尝试为EFv4EFv4.1展示了一些方法。

1

我同意@AbdouMoumen的观点,即在视图层使用模型实体更简单。服务层应该提供一个API来将这些实体持久化到数据存储(数据库)中。服务层不应该愚蠢地复制存储库层(例如:为每个实体保存(entity)),而是提供一个高级别的保存聚合实体的方法。例如,您可以在服务层中有一个Save(order),它会更新更基本的实体,如库存、客户、账户。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接