数据库优先和视图模型

Fra*_*zer 0 asp.net-mvc ef-database-first asp.net-mvc-4

我对数据库优先模型以及如何使用 MVC 视图模型处理这些模型几乎没有经验。

很明显,我无法更改原始模型,但我想为模型添加一些注释以进行验证。

因此,我试图做的是创建一个从实体继承的 ViewModel

我的 DB First 生成的模型 - 不要修改

public partial class xmldata
{
    public string ISBN { get; set; }
    public string title { get; set; }
    public string blurb { get; set; }
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个视图模型,如下所示,它继承自 xmldata

public class XmlDataViewModel : xmldata
{
    [AllowHtml]
    [Display(Name = "Blurb")]
    public string BlurbVm {
        get { return blurb; }
        set { blurb = value; }
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

上面显示的字段我需要 AllowHtml 和我迄今为止最好的解决方案,但是在控制器操作中,我仍然必须手动将 BlurbVm 字段映射回模糊,即使我认为上面的 setter 会处理它(我使用 Automapper对于其他领域)所以我很困惑为什么这不起作用。

此外,目前我正在控制器中进行验证,并且可能希望稍后对其进行重构以将它们移动到视图模型中,以便我可以使用 [Required] 注释以及当前的 [Display (Name="Title")] 字段在视图中处理。

可能我在这里的总体问题是,在使用数据库优先模型时,我是否使用了处理模型注释和视图模型的最佳策略。

Paw*_*rek 5

我想我可能会添加一些关于为什么数据模型与视图模型不同的详细解释

模型和视图模型的区别

正如@Stephen Muecke 在评论中提到的,你正在混合两种不同的东西。视图模型有一个目的 - 从控制器获取数据并将其传输到视图。在复杂的情况下,您要向用户显示的数据与数据库的外观完全不同。要在代码中表示数据结构,请使用数据模型。它的属性与您在数据库中的属性完全相同。

但是,视图模型不应该知道您的数据是如何构建的。您只需简单地分配其属性并将这些数据传递给视图。

考虑以下示例。您的数据库中有CustomersOrders表。

顾客:

ID | Firstname | Lastname
Run Code Online (Sandbox Code Playgroud)

订单:

ID | Amount | CustomerID
Run Code Online (Sandbox Code Playgroud)

为了在您的代码中映射这些数据,您必须创建两个类

public class Customer
{
    public int ID { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

public class Order
{
    public int ID { get; set; }
    public decimal Amount { get; set; }
    public int CustomerID { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是在您的应用程序中,您有一些视图,您希望在其中显示客户的名字和他们在您的商店中花费的总金额。您可以创建视图模型,这将正好用于此目的。

public CustomersViewModel
{
    public string Firstname { get; set; }
    public decimal TotalAmount { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

看看这个视图模型与您的数据模型有何不同?它不知道IDvalue 也不知道Lastname.

此模型仅用于正确显示您的数据,因此您可以在此处使用DataAnnotation您想要的所有s。

public CustomersViewModel
{
    public string Firstname { get; set; }

    [DisplayFormat(DataFormatString="{0:#.####}")]
    public decimal TotalAmount { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

为什么在 MSDN 上他们要注释数据模型?

因为就像@CodeCaster 提到的那样 - 这是不好的做法,但并没有被禁止。如果您的应用程序非常简单,您可以完全跳过视图模型!这是一个坏主意吗?是的 - 即使在简单的情况下,您也应该使用专用视图模型,因为它不会花费您任何费用,但会将您的视图与数据结构分离。我猜他们不想让这些例子复杂化,所以在阅读本教程时,您应该只关注如何使用DataAnnotations。

如何在控制器中绑定自定义视图模型?

视图模型的使用不仅限于将它们返回到视图以简单地显示一些数据。如果您想传递数据供用户修改,您可以使用它们。拥有与数据模型完全相同的属性的视图模型是绝对可以接受的。考虑到前面的例子,我们可以CustomerViewModelEditCustomer.cshtml视图中使用它。

在这个视图中,我们可以让我们的编辑表单看起来像这样

@model CustomerViewModel

// HTML markup
@Html.LabelFor(m => m.Firstname)
@Html.TextboxFor(m => m.Firstname)
// another properties similar
Run Code Online (Sandbox Code Playgroud)

如果我们的Edit方法CustomerController看起来像这样

public Edit(CustomerViewModel customer)
Run Code Online (Sandbox Code Playgroud)

我们要做的事情不多。ASP.NET 将自动绑定customer类型为 的发布表单CustomerViewModel。现在我们只需要将存储的customer数据传递到适当的数据模型中并将其保存在数据库中。