4

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

  1. 在我的数据库中存储 Foo 类型的记录。
  2. 允许用户查找单个 Foo 的记录(将 Foo 的实例传递给视图)。
  3. 允许用户创建 Foo 的新实例(将 Foo 的实例传递给表单)。

假设我也有一个类型 Bar。Bar 包含 Foos 的列表。这里有两个要求:

  1. 用户可以查看 Bar 列表。
  2. 当用户单击特定 Bar 时,它会显示其所有 Foos。

所以,我的基本对象的草图如下所示:

class Foo
{
    string FooName;
    int Id;
}

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

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

  • 视图不应该对任何数据成员有任何写访问权。
  • 有一个视图采用 Bars 列表但不关心 Bar.FooList。假设我也想做好资源管理并尽快关闭 DbContext(即在对象在内存中之后但在渲染视图之前)。如果我只是将 Bars 列表传递给它,而设计器尝试错误地访问 FooList,我们将收到运行时错误。呸!

好的,我只是为每个具有只读数据成员的视图创建一个不同的 ViewModel,没问题。

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

所以,这就是我的架构困境:我想要简洁的视图模型,将视图限制为仅读取它们应该访问的数据。我想避免到处重复数据注释。而且我希望能够尽快积极地释放我的数据库资源。实现我的目标的最佳方式是什么?

4

1 回答 1

0

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

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

public string MyProp { get; set; }

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

至于在验证期间重复错误消息(如果您分别验证 MVC 和 EF 层),您可以使用 resx 资源。

至于释放数据库资源,让 EF 管理它。我发现最好为每个 HttpContext 保留一个 DbContext 实例。您可以使用工厂、OnActionExecuting 操作过滤器、Application_BeginRequest、IoC 容器或其他任何方式打开它。然后在 OnResultExecued、Application_EndRequest 等期间处理上下文。让事情变得简单。

于 2012-07-20T07:42:08.303 回答