【问题标题】:Entity Framework & ASP.NET MVC more complex modelsEntity Framework & ASP.NET MVC 更复杂的模型
【发布时间】:2014-09-27 14:36:44
【问题描述】:

我有实体框架模型,其中包含对其他实体的引用,例如

public class Product
{
    [Key]
    public int ProductID { get; set; }

    [Required]
    public string Name { get; set; }

    [Required]
    public virtual Shop Shop { get; set; }

    [Required]
    public double Price { get; set; }
}

我想创建包含Shop 选择器(DropDown)的编辑视图。

默认情况下,我创建了连接实体模型的基本 MVC 控制器,它创建了如下编辑:

public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    Product product = db.Products.Find(id);

    if (product == null)
    {
        return HttpNotFound();
    }
    return View(product);
}

并且视图不包含商店选择器。

我尝试添加 DropDown 如下:

@Html.DropDownListFor(product => product.Shop, (SelectList)ViewBag.Shops)

但在 POST 方法中,Shop 实体为空。

如何处理?

【问题讨论】:

    标签: c# asp.net-mvc entity-framework


    【解决方案1】:

    创建一个视图模型来表示您想要显示的内容

    public class ProductVM
    {
      public int ProductID { get; set; }
      [Required]
      public string Name { get; set; }
      [Required]
      public int? ShopID { get; set; }
      [Required]
      public double Price { get; set; }
      public SelectList ShopList { get; set; }
    }
    

    在您的控制器中,将您的模型映射到视图模型

    public ActionResult Edit(int? ID)
    {
      ....
      Product product = db.Products.Find(id);
      ProductVM model = new ProductVM();
      // map properties
      ....
      // populate select list (assumes Shop has properties ID and Name)
      model.ShopList = new SelectList(db.Shops, "ID", "Name");
      return View(product);
    }
    

    在你看来

    @model ProductVM
    ....
    @Html.DropDownListFor(m => m.ShopID, Model.ShopList, "--Select shop--")
    @Html.ValidationMessageFor(m -> m.ShopID)
    

    这将使用选定的商店 ID 发回模型。 Select 控制回发单个值,因此您不能回发复杂对象,例如Shop。 POST 方法是

    [HttpPost]
    public ActionResult Edit(ProductVM model)
    {
      ....
    }
    

    请注意,您可以使用automapper 等工具来简化映射

    【讨论】:

    • 你能补充一下这种情况下 POST 方法的样子吗?
    • 我的意思是,如果我的实体模型属性 Shop 和 viewModel 属性 ShopID 中有,我需要编写方法将 VM 转换回模型,例如:Shop = db.Shops.Find(this.ShopID)?对吗?
    【解决方案2】:

    我希望这会有所帮助。

    产品型号:

    public class Product
    {
        public int ProductID { get; set; }
        public string Name { get; set; }
        public int ShopID { get; set; }
        public double Price { get; set; }
    }
    

    然后是产品的 ViewModel:

    public class ProductViewModel
    {
        public Product Model { get; set; }
        public IEnumerable<SelectListItem> Shops{ get; set; }
    
        public ProductViewModel()
        {
             GetShops();
        }
    
        public void GetShops()
        {
            Shops = new List<SelectListItem>();
    
            var collectionShops = GetShopsFromDatabase();
            Shops.AddRange(
                    collectionShops.Select(
                        contract =>
                        new SelectListItem
                        {
                            Text = contract.ShopDescription,
                            Value = contract.ShopID.ToString()
                        }));
        }
    }
    

    在你看来:

    @model ProductViewModel
    
    ....
    
    
    @Html.DropDownListFor(x => x.Model.ShopID, Model.Shops, new { @title = "Please select a shop" })
    

    【讨论】:

    • 首先,Product 是与 EF 相关的数据模型,不应更改。这就是我们使用视图模型的原因。其次,视图模型应该包含与视图相关的属性,而不是方法,当然也不是数据库代码。这是控制器的责任。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多