实体框架服务层更新 POCO
我正在使用服务层 -->存储库 -->实体框架(代码优先)w/POCO 对象 方法,我在更新实体方面遇到了困难。
我正在使用 AutoMapper 将域对象映射到视图模型,这对于获取数据很有用,但如何将更改返回到数据库中?
使用纯 POCO 对象,我会假设没有任何更改跟踪,所以我认为我唯一的选择就是自己处理它。您是否只是确保您的视图模型具有与域对象完全相同的属性?如果我只更改视图模型上的一两个字段怎么办?域对象上的其余字段不会在数据库中被默认值覆盖吗?
话虽如此,最好的方法是什么?
谢谢!
编辑
所以我遇到的问题是这样的,让我们以一个简单的客户
为例:
1)控制器
有一个服务,CustomerService
,调用服务 GetCustmoerByID
方法。
2) Service
调用 CustomerRepository
并检索 Customer
对象。
3) Controller
使用 AutoMapper 将 Customer
映射到 ViewModel
。
4) Controller
将模型交给View
。一切都很棒!
现在,在视图中,您对客户进行一些修改并将其发布回控制器以将更改保存到数据库中。
我假设此时该对象已分离。那么模型是否应该具有与 Customer 对象完全相同的属性?您是否必须为您不想显示的每个项目创建隐藏字段,以便它们可以保留回来?
如何将对象保存回数据库?如果您的视图/模型仅处理对象上的几个字段,会发生什么?
I am using the Service Layer --> Repository --> Entity Framework (Code-First) w/POCO objects
approach, and I am having a hard time with updating entities.
I am using AutoMapper to map my Domain Objects to my View Models and that works good for getting the data, no how do I get that changes back into the database?
Using pure POCO objects, I would assume that there is no sort of change tracking, so I see my only option is to handle it myself. Do you just make sure that your View Models have the EXACT same properties as your Domain Objects? What if I just change a field or two on the View Model? Won't the rest of the fields on the Domain Object get overwritten in the database with default values?
With that said, what is the best approach?
Thanks!
Edit
So what I am stumbling on is this, lets take for example a simple Customer
:
1) The Controller
has a service, CustomerService
, that calls the services GetCustmoerByID
method.
2) The Service
calls into the CustomerRepository
and retrieves the Customer
object.
3) Controller
uses AutoMapper to map the Customer
to the ViewModel
.
4) Controller
hands the model to the View
. Everything is great!
Now in the view you do some modifications of the customer and post it back to the controller to persist the changes to the database.
I would assume at this point the object is detached. So should the model have the EXACT same properties as the Customer
object? And do you have to make hidden fields for each item that you do not want to show, so they can persist back?
How do you handle saving the object back to the database? What happens if your view/model only deals with a couple of the fields on the object?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对于分离的对象,您有责任通知上下文有关分离实体的更改,这是绝对正确的。
基本方法是将实体设置为修改后的。这适用于标量和复杂属性,但不适用于导航属性(FK 关系除外) - 要进一步阅读有关导航属性的问题,请检查 这个答案(它与 EFv4 和 ObjectContext API 相关,但 DbContext API 也存在同样的问题)。这种方法的缺点是DB中的所有字段都会被修改。如果您只想修改单个字段,您仍然必须正确填写其他字段,否则您的数据库记录将被损坏。
有一种方法可以明确定义哪些字段已更改。您将为每个属性而不是整个实体设置修改状态。用通用方法解决这个问题有点困难,但我试图展示一些方法 EFv4 和 EFv4.1 >。
You are absolutely right that with a detached object you are responsible for informing the context about changes in your detached entity.
The basic approach is just set the entity as modified. This works for scalar and complex properties but it doesn't work for navigation properties (except FK relations) - for further reading about problems with navigation properties check this answer (it is related to EFv4 and ObjectContext API but same problems are with DbContext API). The disadvantage of this approach is that all fields in DB will be modified. If you just want to modify single field you still have to correctly fill others or your database record will be corrupted.
There is a way to explicitly define which fields have changed. You will set the modified state per property instead of whole entity. It is little bit harder to solve this on generic approach but I tried to show some way for EFv4 and for EFv4.1.
我同意@AbdouMoumen 的观点,即在视图级别使用模型实体要简单得多。服务层应提供 API 将这些实体保存在数据存储 (db) 中。服务层不应该愚蠢地复制存储库律师(即:为每个实体保存(实体)),而是为实体聚合提供高级保存。例如,您可以在服务层中进行保存(订单),这会导致更新更多基本实体,例如库存、客户、帐户。
I agree with @AbdouMoumen that it's much simpler to use the model entities at the view level. The service layer should provide an API to persist those entities in the data store (db). The service layer shouldn't dumbly duplicate the repository lawyer (ie: Save(entity) for every entity) but rather provide a high level save for an aggregate of entities. For instance, you could have a Save(order) in the service layer which results in updating more basic entities like inventory, customer, account.
如果您使用 EF Code First,即:DbContext API,那么您仍然可以进行更改跟踪,该更改跟踪由您的上下文类负责。
对对象进行更改后,您所要做的就是在上下文中调用
SaveChanges()
,这会将更改保存到数据库中。编辑:
由于您使用 AutoMapper 创建实体的“副本”,因此它不再附加到您的上下文。
我想您可以做的事情与您在 ASP.NET MVC 中所做的事情类似(使用
UpdateModel
)。您可以从上下文中获取原始实体,获取 ViewModel(可能包含更改的属性)并更新旧实体,手动(仅修改属性)或使用 AutoMapper。然后使用 context.SaveChanges() 保存更改。另一种解决方案是将模型实体作为 ViewModel 的[一部分]发送。这样,您的实体就会附加到容器,并且更改跟踪仍然有效。
希望这有帮助:)
If you're using EF Code First, i.e: the DbContext API, then you still do have change tracking which is taken care of by your context class.
after making changes to your objects, all you have to do is call
SaveChanges()
on your context and that will persist the changes to your database.EDIT:
Since you are creating a "copy" of the entity using AutoMapper, then it's no longer attached to your context.
I guess what you could do is something similar to what you would in ASP.NET MVC (with
UpdateModel
). You can get the original entity from your context, take your ViewModel (which may contain changed properties) and update the old entity, either manually (just modified properties), or using AutoMapper. And then persist the changes usingcontext.SaveChanges()
.Another solution would be to send the model entity as [part of] the ViewModel. This way, you'll have your entity attached to the container and change tracking will still work.
Hope this helps :)