2
  1. 模型和视图模型有什么区别?我应该同时使用它们还是最好跳过其中一个?谁从数据库中获取数据?

  2. 我想知道从数据库中获取数据的最佳/正确方法是什么。

一种选择是有一个 DAL(数据访问层)并在每个控制器中实例化它,用它填充视图模型,如:

var viewmodel = Dal.GetArticles();

另一种选择是让模型本身从数据库中获取信息:

var model = new ArticlesModel();
model.GetArticles();

public void GetArticles()
{
var context = new DbContext();
_articles = context.Articles
}

另一个类似的选择是拥有一个静态 DAL,这样您就可以在每个模型中访问它,因此每个模型都有一个使用静态 DAL 类获取数据的方法(其中包含一个 DbContext 类来访问数据库)

public void GetArticles()
{
_articles = DAL.GetArticles();
}

所以一般的问题是模型本身是否需要从数据库中获取数据,或者控制器本身是否可以访问 DAL。

4

3 回答 3

4

当有人在写一个更有用的答案时,我会很快解决你的观点。

Model是您要显示的数据。

通常,您会希望使用对象关系映射,以便您的大多数业务对象类对应于数据库表,而您不必手动构造查询。

有很多可用的 ORM 解决方案,包括实体框架、NHibernate 和(现在正在死去的)LINQ to SQL。

还有一个很棒的 micro-ORM,称为Dapper,如果更大的框架对您的解决方案感到不必要的臃肿,您可能会喜欢它。

确保您了解它们之间的差异。

DAL 在 .NET 中比“知道”如何加载自己的类更惯用。

(虽然在实践中你的解决方案很可能是两种方法的混合——关键是,像往常一样,保持平衡。)

我的建议是,只要你的 ORM 允许并且不会给调用代码增加额外的复杂度, 就尽量让你的模型保持普通的旧 CLR 对象。

这些对象,只要有可能(并且是明智的——任何规则都有例外!),不应该绑定到特定的数据库或 ORM 实现。

如果需要,将您的代码迁移到另一个 ORM 将只是重写数据访问层的问题。
但是,您应该明白,这不是分离 DAL 的主要原因。

您不太可能在项目中间更改 ORM,除非您最初的选择确实不适合该目的,或者您突然吸引了 100,000 名用户并且您的 ORM 无法处理它。一开始就对此进行优化是非常愚蠢的,因为它会分散您的注意力,使您无法创建能够吸引您正在优化的点击量的一小部分的出色产品。(免责声明:我以前走过这条路。)

相反,DAL 的好处是您的数据库访问变得总是明确的并且被限制在您希望它发生的某些地方。例如,接收到要显示的模型对象的视图不会试图从数据库中加载某些内容,因为实际上这是控制器的工作。

将诸如业务逻辑、表示逻辑和数据库逻辑之类的东西分开通常也很好。很多时候,它会产生更好、更少错误的代码。另外:您可能会发现很难对依赖于从数据库加载的对象的任何代码进行单元测试。另一方面,使用 LINQ 创建一个“假”的内存数据访问层是微不足道的。

请记住,这条规则也有例外,例如由许多 ORM 生成的惰性属性,它们会在运行中加载关联的对象——即使在视图中调用也是如此。因此,重要的是您应该做出明智的决定,何时允许数据访问以及为什么。语法糖可能很有用,但如果您的团队不知道从 ORM 加载 20,000 个对象的性能影响,这将成为一个问题。

在使用任何 ORM 之前,请先了解它是如何工作的

在 Active Record 风格的对象和 DAL 之间进行选择主要取决于品味、.NET 中的常见习语、团队习惯以及 DAL 最终可能不得不被替换的可能性。

最后,ViewModels 是另一种野兽。

试着这样想它们:

  1. 视图中不应该有任何比if-then-else.
  2. 然而,在展示事物时往往一些复杂的逻辑。 考虑分页、排序、在一个视图中组合不同的模型、了解 UI 状态。

这些是视图模型可以处理的事情。
在简单的情况下,它只是将几个不同的模型组合成一个“视图模型”:

class AddOrderViewModel {
    // So the user knows what is already ordered
    public IEnumerable<Order> PreviousOrders { get; set; }
    // Object being added (keeping a reference in case of validation errors)
    public Order CurrentOrder { get; set; }
}

模型只是数据,控制器组合数据并引入一些逻辑来描述在视图模型中显示的数据,而视图只是呈现视图模型。

视图模型也可以作为一种文档。他们回答了两个问题:

  1. 我可以在视图中使用哪些数据?
  2. 我应该在控制器中准备哪些数据?

不要将对象传递到ViewData并记住它们的名称和类型,而是使用通用视图并将内容放入ViewModel的属性中,这些属性是静态类型的,可用于 IntelliSense。

此外,您可能会发现创建ViewModel层次结构很有用(但不要走极端!)。例如,如果您的站点范围的导航从面包屑更改为其他内容,那么只需替换基本视图模型上的属性、显示它的局部视图以及在基本控制器中构造它的逻辑就很酷。保持理智。

于 2012-06-09T14:01:14.987 回答
2

模型代表您喜欢数据的结构,而不关心可能使用它的视图。模型的意图纯粹是表示结构的意图。

模型可能包含与使用它的视图无关的属性。

视图模型的设计考虑了视图。视图模型旨在与视图建立一对一的关系。视图模型仅包含其预期视图所需的基本字段和属性。

通常,您会让控制器联系存储库(在您的示例中为 DAL)获取数据,然后使用结果填充模型或视图模型,将其发送到视图。

于 2012-06-09T13:56:28.203 回答
1

模型(领域模型):是应用程序的核心,代表了最大和最重要的业务资产,因为它捕获了所有复杂的业务实体、它们的关系和它们的功能。

ViewModel:位于 Model 之上的是 ViewModel:ViewModel 的两个主要目标是 1. 使 View 易于使用 Model 和 2. 将 Model 与 View 分离和封装。

例如。

模型:

public class Product
{
...............
}

public class Category
{
...........
}

视图模型:

public class ProductViewModel
    {
        public ProductViewModel(List<Product> products, List<Category> categories)
        {
            this.Products = products;
            this.Categories = categories;
        }

        public List<Product> Products { get; set; }
        public List<Category> Categories { get; set; }

    }
于 2012-06-09T14:08:32.457 回答