2010-12-16 83 views
1

我建设,我使用下面流动的ASP.NET MVC应用程序:AutoMapper的体系结构?

获取实体

  1. 运行动作在控制器
  2. 从FactoryClass获取数据,对模型进行操作(实体框架)
  3. 获取数据返回到控制器中的操作
  4. 使用AutoMapper从Model对象转换为ModelView对象
  5. 回归模型视图对象的强类型查看

更新实体

  1. 运行动作与模型视图实体输入(DefaultDataBinder将被使用)
  2. 验证模型视图实体
  3. 直接将ModelView对象发送给正确的工厂方法。
  4. 检查ModelView对象是否有标识,如果是这样从数据库中获取Model对象
  5. 使用AutoMapper将传入的ModelView对象转换为Model对象/实体。如果其更新,则使用提取的Model对象作为目标。
  6. 如果是更新使用刷新Client.Wins其他使用添加
  7. 运行SaveChanges并返回到控制器。

问题1

的模型视图的类被特制用于该复合控制器操作被连接到(它可以同时包含edeting对象和列表)的意见。不同视图的几个动作使用相同的ModelView类是很常见的,这意味着ModelView对象中的所有对象都不会用在每个动作/视图中。

只要查看使用可更新是没有问题的,但ModelViewObjects的所有属性...

说,我们得到了一些地方的ModelViewObject的属性不使用视图,这ModelViewObject被发送到工厂(将被更新),在该工厂中获取corsponding ModelObject(从数据库/实体框架),然后用AutoMapper与ModelViewObject合并。这里的问题是未设置ModelViewObject的属性(未在视图中使用)将导致在ModelObject中覆盖实际数据。

为了解决这个ü通常使用AutoMapper ForMember Ignor(),但这将是当完整ModelViewObject(所有属性设置)将更新数据库的一个问题。

你是如何处理这个问题的?在不同的AutoMapper设置下的Factorys中有不同的更新方法吗?

这将是很好,如果我只能有一个这样的方法:UpdateMyEnityt(myEntity所实体),这methid将更新OCH myEntity所添加的对象。

问题2

我应该在哪里放置AutoMapper映射?到目前为止,我已经在控制器中放置了更新获取。我曾想过在ModelViewObject中放置映射,例如ModelViewObject.ToDataModel,但如果我不需要完整的翻译(som属性将被忽略),那么我将不得不在AutoMapper中执行其他位置。

你是如何处理这个问题的?

问题3

说,你已经在我们的工厂类的工作更新方式使用AutoMapper与SOM ignors翻译一个ModelViewObject到模型视图(实体框架对象)。现在说我们用新的字段/属性更新了数据库表,如果我们运行一个视图来处理与此表对应的ModelViewObject,但不处理新的属性,这将意味着属性将始终设置为空/字符串。空/ 0。在工厂运行常规更新方法时,不会忽略此属性,这意味着零值会覆盖实际值。

这是一种很大的风险,这种更新将会完成,而且我不会记得在旧代码中处理这种更新的风险。

我该如何处理?

问题4 AutoMapper有一个验证方法,您可以检查是否映射将成为可能,现在我有这些验证其中映射完成后,我应该莫比把这个在其他一些方法,其中验证将会像应用程序启动一样快地执行?使用该功能时,映射中的其他问题将首先显示。

BestRegards

+5

存在这个问题太大 - 考虑总结段落 - 这是一个Q&A论坛,不是散文写作。 :) – RPM1984 2010-12-16 10:49:55

+0

Yhea我知道,但我讨厌问题,以保持它更短,有这么多,可以决定什么aswear可能。 – Banshee 2010-12-16 13:54:24

回答

4

首先,你应该使用视图模型为每个视图。并只提取你需要的日期。 您应该为“困难”问题添加设备以手动映射。 我认为AutoMapper是从Db对象到View对象的传输日期的错误方式。

+0

谢谢,但即使我决定对每个视图和手动映射使用ViewModel,当业务实体从数据库更新为新的/更改的属性时,总是会出现问题。如果应用程序很大,那么我可能找不到破解映射。这是很久以前有几种观点使用相同的商业实体。 – Banshee 2010-12-16 13:41:38

+0

假设Page1需要视图来包含复杂的类MyFilters,这个类包含了很多参数。我的Page2也需要这个班。将同一个班级同时添加到两个视图是否是错误的?如果不是的话,会有很多额外的代码做或多或少的相同的事情。 – Banshee 2010-12-16 13:53:23

+0

如果你在不同的页面上有相同的控件,你应该通过UI.so设计你的ViewModel。你应该使用相同的viewModel。像:具有相同属性的Page1和Page2 MyFilter是我们页面的视图模型。 – 2010-12-16 14:08:58

1

问题1:如果您使用的是不同的视图,请使用不同的ViewModel。这样,只有显示的属性才会自动映射。

问题2:不同Automapper设置在每一个项目与

Project1.AutomapperSettings.Execute(); 
Project2.AutomapperSettings.Execute(); 

在Global.asax或类似入口点。

问题3:见问题1

问题4:使用ValidationAttribute在视图模型的属性,让MVC照顾它

+0

问题1:听起来不错,问题2:请认真解释一下,你的意思是Mapper.Create应该放在我放置的地方,但Mapper.AssertConfigurationIsValid();应该从Gloval.asax运行?问题3:好吧,我看到问题4:我不是在谈论实体验证,而是在谈论Mapper阈值(Mapper.AssertConfigurationIsValid();) – Banshee 2010-12-16 13:48:14

+0

说Page1需要视图来包含复杂的类MyFilters,该类包含很多参数。我的Page2也需要这个班。将同一个班级同时添加到两个视图是否是错误的?如果不是的话,会有很多额外的代码做或多或少的相同的事情。 – Banshee 2010-12-16 13:54:52

+0

问题2:应用程序加载时应该创建AutoMapper映射,因为它们属于一个静态类,并且在应用程序的整个生命周期中都存在。 问题4:Mapper.AssertConfigurationIsValid();应该只能在单元测试中运行,而不能作为应用程序逻辑afaik的一部分。 评论2:将ViewModel1映射到Model并将ViewModel2映射到Model,并考虑ViewModel的继承。否则,你可能完全删除ViewModels,因为你没有使用它们来过滤/重构你的模型? – Kaido 2010-12-16 16:14:02