架构:在MVC / Entity Framework Project中避免重复的模型/模型视图代码

时间:2012-07-20 02:06:38

标签: asp.net-mvc

我是整个ASP世界的新手,我正在通过构建C#MVC3 / EF4项目来解决问题。我发现很难避免在我的模型和视图模型中复制一堆代码。考虑一个对象Foo。我需要用Foo做以下事情:

  1. 将Foo类型的记录存储在我的数据库中。
  2. 允许用户查找单个Foo的记录(将Foo的实例传递给视图)。
  3. 允许用户创建Foo的新实例(将Foo的实例传递给表单)。
  4. 假设我也有一个类型吧。一个栏包含一个Foos列表。这里有两个要求:

    1. 用户可以查看条形码列表。
    2. 当用户点击特定栏时,它会显示所有的Foo。
    3. 因此,我的基本对象的草图如下所示:

      class Foo
      {
          string FooName;
          int Id;
      }
      
      class Bar
      {
          List<Foo> FooList;
          int Id;
          string Baz;
      }
      

      但是当我开始考虑不同的观点时,它开始变得混乱:

      • 视图不应具有对任何数据成员的任何写入权限。
      • 有一个视图采用Bars列表但不关心Bar.FooList。假设我也想要善于资源管理并尽快关闭DbContext(即在对象在内存之后但在渲染视图之前)。如果我只是传递一个Bars列表并且设计者试图错误地访问FooList,我们将得到一个运行时错误。呸!

      好的,我只是为每个只读数据库的视图创建一个独特的ViewModel,没问题。

      • 但是数据库模型和表单模型都需要附加DataAnnotations,说明需要哪些字段,字符串的最大长度等。如果我创建单独的表单模型和数据库模型,那么我最终必须复制所有这些注释。呸!

      所以,这是我的架构困境:我希望拥有简洁的视图模型,这些模型仅限于查看他们应该访问的数据。我想避免在整个地方重复数据注释。我希望能够尽快积极地释放我的数据库资源。实现目标的最佳方式是什么?

1 个答案:

答案 0 :(得分:0)

我的建议是不要在EF实体类中使用数据注释。相反,尝试流畅的API。它将持久性问题保留在模型类本身之外。您甚至可以在完全不同的库中定义模型构建器。

对于具有重复属性,属性很便宜:

public string MyProp { get; set; }

不是很多代码,您可能会开始看到,视图模型和实体不必总是完全相互重复。例如,如果要将[HiddenInput]应用于视图模型,使其呈现为<input type="hidden" />,该怎么办?你会将它应用于实体吗?为什么?它属于viewmodel(命名空间甚至是System.Web.Mvc,而不是System.ComponentModel.DataAnnotations)。

至于在验证期间复制错误消息(如果单独验证MVC和EF层),则可以使用resx资源。

就释放数据库资源而言,让EF管理它。我发现每个HttpContext最好保留一个DbContext实例。您可以使用工厂,OnActionExecuting操作过滤器,Application_BeginRequest,IoC容器或其他任何东西来打开它。然后在OnResultExecued,Application_EndRequest等期间处理上下文。保持简单。