2014-09-26 91 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