3

我正在使用这种Service Layer --> Repository --> Entity Framework (Code-First) w/POCO objects方法,并且很难更新实体。

我正在使用 AutoMapper 将我的域对象映射到我的视图模型,这对于获取数据很有用,不知道如何将这些更改恢复到数据库中?

使用纯 POCO 对象,我会假设没有任何变化跟踪,所以我看到我唯一的选择是自己处理它。您是否只是确保您的视图模型具有与您的域对象完全相同的属性?如果我只是更改视图模型上的一两个字段怎么办?域对象上的其余字段不会在数据库中被默认值覆盖吗?

话虽如此,最好的方法是什么?

谢谢!

编辑

所以我绊倒的是这个,让我们举一个简单的例子Customer

1)Controller有一个CustomerService调用 servicesGetCustmoerByID方法的服务。

2)Service调用CustomerRepository并检索Customer对象。

3)Controller使用 AutoMapper 映射CustomerViewModel.

4)Controller将模型交给View. 一切都很好!

现在在视图中,您对客户进行了一些修改并将其发布回控制器以将更改持久保存到数据库中。

我会假设此时对象已分离。那么模型应该具有与对象完全相同的属性Customer吗?并且您是否必须为您不想显示的每个项目创建隐藏字段,以便它们可以保留回来?

您如何处理将对象保存回数据库?如果您的视图/模型只处理对象上的几个字段会发生什么?

4

3 回答 3

5

如果您使用的是 EF Code First,即:DbContext API,那么您仍然拥有由上下文类负责的更改跟踪。

对对象进行更改后,您所要做的就是调用SaveChanges()您的上下文,这会将更改持久保存到您的数据库中。

编辑

由于您正在使用 AutoMapper 创建实体的“副本”,因此它不再附加到您的上下文中。

我猜您可以做的事情类似于您在 ASP.NET MVC 中所做的事情(带有UpdateModel)。您可以从上下文中获取原始实体,获取 ViewModel(可能包含更改的属性)并手动更新旧实体(仅修改属性)或使用 AutoMapper。然后使用context.SaveChanges().

另一种解决方案是将模型实体作为 ViewModel 的 [一部分] 发送。这样,您将实体附加到容器,并且更改跟踪仍然有效。

希望这可以帮助 :)

于 2011-04-22T17:08:41.267 回答
3

你是绝对正确的,对于一个分离的对象,你负责通知上下文你的分离实体的变化。

基本方法只是将实体设置为已修改。这适用于标量和复杂属性,但不适用于导航属性(FK 关系除外)-有关导航属性问题的进一步阅读,请检查此答案(它与 EFv4 和 ObjectContext API 相关,但与 DbContext API 有相同的问题) . 这种方法的缺点是DB中的所有字段都会被修改。如果您只想修改单个字段,您仍然必须正确填写其他字段,否则您的数据库记录将被损坏。

有一种方法可以显式定义哪些字段已更改。您将设置每个属性而不是整个实体的修改状态。在通用方法上解决这个问题有点困难,但我试图为EFv4EFv4.1展示一些方法。

于 2011-04-22T17:52:55.990 回答
1

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

于 2012-08-26T04:52:34.043 回答