ViewModel возвращает одинаковые значения для всех 500 записей в представлении

#c# #asp.net-mvc #viewmodel #asp.net-mvc-viewmodel

#c# #asp.net-mvc #viewmodel #asp.net-mvc-viewmodel

Вопрос:

Я новичок в использовании ViewModels, здесь у меня есть новый список, и я добавляю в него элементы, просматривая таблицу базы данных. Проблема в том, что все возвращаемые записи идентичны, используя одну и ту же запись снова и снова. В чем может быть проблема и является ли это хорошим способом выполнить заполнение данными и передачу ViewModel или есть способ получше? Прямо сейчас он возвращает около 500 записей с одинаковыми данными.

 public class DimCustomersController : Controller
{
    private AdventureWorks_MBDEV_DW2008Entities db = new AdventureWorks_MBDEV_DW2008Entities();

    public ActionResult CustomersIndexVM()
    {
        List<DimCustomersIndexViewModel> CustomerList = new List<DimCustomersIndexViewModel>();

        DimCustomersIndexViewModel CustomerItem = new DimCustomersIndexViewModel();
        foreach (var m in db.DimCustomers.ToList())// cold do for loop up to count
        {
            CustomerItem.Title = m.Title;
            CustomerItem.FirstName = m.FirstName;
            CustomerItem.MiddleName = m.MiddleName;
            CustomerItem.LastName = m.LastName;
            CustomerItem.BirthDate = m.BirthDate;
            CustomerItem.MaritalStatus = m.MaritalStatus;
            CustomerItem.Suffix = m.Suffix;
            CustomerItem.Gender = m.Gender;
            CustomerItem.EmailAddress = m.EmailAddress;
            CustomerItem.AddressLine1 = m.AddressLine1;
            CustomerItem.AddressLine2 = m.AddressLine2;
            CustomerItem.Phone = m.Phone;
            //other columns go here
            CustomerList.Add(CustomerItem);
        }

        return View("CustomersIndexVM", CustomerList);
    }
  

Комментарии:

1. Помимо инициализации view model внутри цикла в соответствии с ответами, вы также можете просто использовать var CustomerList = db.DimCustomers.Select(x => new DimCustomersIndexViewModel { Title = x.Title, FirstName = x.FirstName, ...... }.ToList();

Ответ №1:

Эта строка должна быть внутри цикла:

DimCustomersIndexViewModel CustomerItem = new DimCustomersIndexViewModel();

Причина в том, что вам нужна новая модель представления для каждого клиента, но вместо этого вы в настоящее время создаете только одну модель представления и изменяете ее свойства. Когда вы добавляете его в список, вы не добавляете копию; вы добавляете ту же модель представления, которую вы уже добавили.

Этот код работал бы, если бы DimCustomersIndexViewModel был структурой, потому что структуры — это просто набор значений, которые не имеют внутренней идентичности, и на них копируются, а не ссылаются. (Техническое сравнение.) Но это класс (как и должно быть) с уникальным идентификатором, поэтому вы добавляете ссылку на модель single view в список снова и снова. Customerlist[0] и CustomerList[1] и все остальные элементы указывают на один и тот же DimCustomersIndexViewModel экземпляр объекта, свойства которого затем перезаписываются и остаются равными самому последнему клиенту.

Перемещая эту строку внутрь цикла, вы создаете отдельный цикл DimCustomersIndexViewModel для каждого клиента, каждый со своим собственным набором свойств, и CustomerList содержит ссылки на множество различных DimCustomersIndexViewModel экземпляров объекта.

Как только у вас появится солидный опыт работы с этой концепцией, следующим шагом может стать использование AutoMapper, чтобы вам не приходилось вести список всех свойств в вашем коде здесь.

Ответ №2:

Проблема в том, что вы добавляете один и тот же ссылочный объект во время каждой итерации вашего цикла. Этот объект никогда не изменяется (вы никогда new не запускаете его снова), но вы меняете свойства объекта. Затем вы добавляете этот объект снова и снова. Вам нужно обновлять этот объект на каждой итерации цикла.

Комментарии:

1. Спасибо, это была проблема; удивительно, как я пропустил простые вещи 🙂