繁体   English   中英

我需要在MVC5的ViewModel中实例化我的Model类吗?

[英]Do I need to instantiate my Model class in a ViewModel in MVC5?

我是MVC5的新手,只是试图掌握ViewModels的使用。 我的问题是,是否必须在ViewModel的控制器中实例化模型类。 我正在建立一个数据库来组织账单,并拥有一个映射到数据库表的Cash模型,以及一个可以查看/编辑数据的CashViewModel。

这是我的模型:

public class Cash
{
    public int CashId { get; set; }
    public decimal CashAmount { get; set; }
    public int CashTypeId { get; set; }
    public DateTime DateModified { get; set; }
    public CashType CashType { get; set; }
}

这是我的ViewModel:

public class CashViewModel
{
    public int CashId { get; set; }
    public decimal CashAmount { get; set; }
    public int CashTypeId { get; set; }
    public SelectList CashTypeSelectList { get; set; }
}

这是我的控制器:

public ActionResult Create([Bind(Include = "CashAmount,CashTypeId")] CashViewModel cashVM)
    {
        if (ModelState.IsValid)
        {
            var cash = db.Cashes.Create();
            cash.DateModified = DateTime.Now;
            cash.CashAmount = cashVM.CashAmount;
            cash.CashTypeId = cashVM.CashTypeId;
            db.Cashes.Add(cash);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.CashTypeId = new SelectList(db.CashTypes, "CashTypeId", "CashTypeName", cashVM.CashTypeId);
        return View(cashVM);
    }

我正在创建Cash模型的实例,并将ViewModel类映射到我的模型类。 这个对吗? 当我开始在一个ViewModel中有多个具有多个属性的Models的项目开始时,这似乎会很快失去控制。

我阅读的所有问题和文章要么太含糊,要么太详细,对于我的特定问题我找不到任何东西,对不起,如果已经有东西了。

ViewModels基本上是为了在View和Controller之间提供DTO,就像您所做的那样。 但是,您的模型看起来不对,因为您应该仅具有CashType,而不能具有CashTypeId,因为CashType模型具有Id,而Cash具有对其的引用。 两者的问题在于它们无法保持同步,我什至都不记得EF选择哪一个权威。

除此之外,您似乎已经解决了。 您的ViewModel具有一个SelectList,其中包含要呈现的视图的值和一个CashTypeId,供客户端将其分配给该值。 在主要实体上没有CashTypeId的情况下,您将不得不创建一个新的CashType对象并为其分配适当的ID(假设这是Entity Framework)。

最后一条建议:不要在控制器中执行这些数据库操作。 检查存储库模式 ,甚至可以在它们之间放置一个业务层。

我正在创建Cash模型的实例,并将ViewModel类映射到我的模型类。 这个对吗? 当我开始在一个ViewModel中有多个具有多个属性的Models的项目开始时,这似乎会很快失去控制。

您所做的没有错。 但是,要从域模型到视图模型(视图模型)映射,可以使用库为您进行映射。 我使用AutoMapper 想象一下你有这个:

public class Cash {
   public string Prop1 { get; set; }
}

public class CashViewModel {
   public string Prop1 { get; set; }
}

Application_Start()启动方法中,您可以指示AutoMapper如何从域模型映射到模型的视图,如下所示:

protected void Application_Start()
{
   // ReverseMap will do vice-versa mapping
   // If property names are the same, then AutoMapper will take care of it
   // for you.
   Mapper.Initialize( x => x.CreateMap<Cash, CashViewModel>().ReverseMap() );

   // Of course you will have many cases where the property names 
   // are different
   // For that case you will need to do this
   // Imagine your model has a property called Name and view model has
   // FirstName
   Mapper.CreateMap<CashViewModel, Cash>()
            .ForMember(model => model.Name, map => map.MapFrom(vm => vm.FirstName));
}

然后在您的控制器中,您只需执行此操作即可将视图模型转换为域模型:

var model = Mapper.Map<Cash>( cashViewModel );

这种方法的优点在于,所有映射都将放在一个地方。 总之, 是一篇很棒的文章,涵盖了您正在寻找的大部分内容以及更多内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM