2014-09-26 2 views
0

У меня есть Entity Framework модель, которая содержит ссылку на другой Сущности, какEntity Framework и 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; } 
} 

Я хотел бы создать Edit View, которые содержат Shop селектор (DropDown).

По умолчанию я создал базовый MVC контроллер с Entity модели, связанной, создавшей Edit, как:

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); 
} 

и вид не содержит селектор Shop.

Я пытался добавить DropDown как:

@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) 

это разместит назад модель с выбранным идентификатором Shop. Select контролирует отправку однократных значений, поэтому вы не можете отправить обратно сложный объект, такой как Shop. Метод POST будет

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

Примечание вы можете использовать такие инструменты, как automapper сделать отображение проще

+0

вы можете добавить, как метод POST будет выглядеть в этом случае? – Tomasz

+0

Я имею в виду, если у меня есть в моем магазине свойств объекта Entity, и в моем представлении PropertyModel свойство ShopID, мне нужно написать метод для преобразования обратно VM в модель, например: 'Shop = db.Shops.Find (this.ShopID)'? правильно? – Tomasz

+1

Да, это правильно. –

1

Надеюсь, это поможет.

Модель продукта:

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

Во-первых, 'Product' модель данных, связанных с EF и не должны быть изменены. Вот почему мы используем модели просмотра. Во-вторых, модели просмотра должны содержать свойства, относящиеся к представлению, а не методы и, конечно, не код базы данных. Это ответственность диспетчера. –

Смежные вопросы