Модель представления MVC 5 и несколько таблиц

#viewmodel #ienumerable #multiple-tables #asp.net-mvc-5

#модель представления #ienumerable #несколько таблиц #asp.net-mvc-5

Вопрос:

Я только что закончил 2 представления, вставку и индексное представление, и я должен сказать, что нелегко работать с несколькими таблицами. «Вставка» была самой простой, мне просто нужно было добавить в 2 разные таблицы:

 [HttpPost]
public ActionResult Index(CustPlayerVM custPlayer)
{
    var Cust = new Cust()
    {
        CustID = custPlayer.CustID,
        Color = custPlayer.Color
    };
    var Player = new Player()
    {
        PlayerName = custPlayer.PlayerName
    };
    db.Custs.Add(Cust);
    db.Players.Add(Player);
    db.SaveChanges();
    return View();
}
  

Проблема в том, что у меня были всевозможные ошибки при List<> IEnumerable<> попытке закодировать представление. Либо вы получаете страшную ошибку «элемент модели, переданный в словарь, имеет тип», либо нулевую ссылку в представлении при обработке цикла «foreach». Это было чудо, что это сработало, но я не могу сказать вам, почему. Вот почему я отправил вопрос для начала.

Вот как выглядит «представление»:

 public ActionResult List()
{
    ViewBag.Message = "custPlayer";
    //CustPlayerVM vm = new CustPlayerVM();      

    List<object> vm = new List<object>();
    vm.Add(db.Custs.ToList());
    vm.Add(db.Players.ToList());          
    ViewBag.PlayerCnt = db.Players.Count();
    return View(vm);
}
  

Обратите внимание на List<object> (в отличие от модели представления, которая закомментирована).

И это представление:

 @model IEnumerable<object> @{ 
    List<viewModelA.Cust> lstCust = Model.ToList()[0] as List<viewModelA.Cust>;
    List<viewModelA.Player> lstPlayer = Model.ToList()[1] as List<viewModelA.Player>; }   

@Html.ActionLink("Create New", "Create") </p> 
<table class="table">
    <tr>
        <th>
            @Html.Raw("Color")
        </th>
        <th>
            @Html.Raw("CustID")
        </th>
        <th>
            @Html.Raw("ID")
        </th>
        <th>
            @Html.Raw("Player Name")
        </th>
        <th>
            @Html.Raw("PlayerID")
        </th>
    </tr>
    amp;nbsp;
    @for (int i = 0; i < ViewBag.PlayerCnt; i  )
    {
        <tr>
            <td>@lstCust[i].Color</td>
            <td>  @lstCust[i].CustID</td>
            <td>  @lstCust[i].ID </td>
            <td>   @lstPlayer[i].PlayerName  </td>
            <td> @lstPlayer[i].ID</td>
        </tr>
    } 
</table>
  

Мне пришлось обернуть цикл for вокруг кода, потому что foreach выполнялся для каждой таблицы отдельно.

В будущем, как вы должны иметь дело с IEnumerable анонимными типами vs? Это не должно быть так сложно, правильно?

Ответ №1:

Для улучшения вашего кода я настоятельно рекомендую подробнее изучить основы ООП и основы .NET, в том числе как работать с коллекциями ( Array , List , Collection , IEnumerable , foreach ).

Тогда будут очевидны следующие идеи:

  1. Создайте общий класс ViewModel, который будет представлять состояние представления

      class PersonViewModel
     {
        public int CustID { get; set; }
        public string Color { get; set; }
        public string PlayerName { get; set; }
     }
      
  2. Используйте этот общий класс для вашего представления

      public ActionResult List()
     {
        var viewModel = new List<PersonViewModel>();      
        viewModel.Add(db.Custs.ToArray());
        viewModel.Add(db.Players.ToArray());          
    
        return View(viewModel);
     }
      
  3. Вместо списка универсального Object типа примените коллекцию вашего PersonViewModel типа

          @model IEnumerable<PersonViewModel>
    
         <table class="table">
           @foreach(var personVM in Model){
             <tr>
                <td>@personVM.Color</td>
                <td>@personVM.CustID</td>
                <td>@personVM.PlayerName</td>
             </tr>
            } 
         </table>