2014-09-26 51 views
0

我有一个包含参考其他实体一样实体框架和ASP.NET MVC更复杂的模型

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选择(下拉)实体框架模型。

默认情况下,我已经创建了基本的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); 
} 

和视图不包含购物选择。

我试图添加下拉像:

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

但在POST方法,本店实体为空。

如何处理?

回答

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使地图更容易

+0

请问您可以在这种情况下添加POST方法的样子吗? – Tomasz 2014-09-27 06:33:35

+0

我的意思是,如果我在我的实体模型属性商店,并在我的viewModel属性ShopID,我需要编写的方法来将虚拟机转换回模型,如:Shop = db.Shops.Find(this.ShopID)'?对? – Tomasz 2014-09-27 06:48:53

+1

是的,这是正确的。 – 2014-09-27 06:50:04

1

我希望这有助于。对于产品

型号:

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

然后一个视图模型的产品:

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" }) 
+0

首先,'Product'是关系到EF数据模型,不应该被改变。这就是我们使用视图模型的原因。其次,视图模型应该包含与视图相关的属性,而不是方法,当然不包含数据库代码。这是控制器的责任。 – 2014-09-27 03:43:00