Может ли отображение класса на себя с помощью automapper быть хорошим решением, чтобы разбить большие представления?

У меня довольно длинный модельный класс с множеством свойств и полей навигации.

public class Customers
{
    public Customers()
    {
        this.Files = new HashSet<Files>();
    }

    public int CustomerID { get; set; }
    public int InspectionID { get; set; }
    public int Position { get; set; }
    public Nullable<int> Height { get; set; }
    public Nullable<int> Weight{ get; set; }
    //.....many more properties
//there are some navigation properties below
//.....
}

Чтобы разбить представление (а этого требует бизнес-логика), я создал около 14 частичных представлений, которые имеют подмножества свойств в этом классе, и соответствующее частичное представление загружается в основное представление редактирования при загрузке страницы.(Обновляется после комментарии) В другом представлении при щелчке ссылки вызывается действие редактирования GET с параметром CustomerID, передаваемым контроллеру, который загружает представление редактирования с соответствующим частичным представлением, например так:

@model myApplication.Models.CustomersViewModel //Trial 2 from below uses                    //this and 
@model myApplication.Models.Customers //Trial 1 from below uses this 
 
@{
    ViewBag.Title = "Edit";
}
@section Styles {
}
<h2>Edit</h2>
@using (Html.BeginForm())
{
   @Html.AntiForgeryToken()
        <div>
          @*All commong properties here*@
        </div>
          
    @*the corresponding PartialView with subset /selected/ properties here -UPDATE: please note that the partailview is named as the PK i.e. inspection id (Sorry, I worte wrongly on the initial post)
  
    @Html.Partial("_edittemplates/" + Model.InspectionID)

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </div>
    </div>

Теперь я не хочу создавать 14 ViewModel для каждого из 14 частичных представлений с подмножествами этих свойств, потому что это казалось расточительным. То, что я хотел сделать, это использовать один большой ViewModel и использовать automapper для управления тем, какие свойства загружены в представлении (как из основного, так и из частичного), и отобразить эти конкретные свойства без необходимости дублировать (копировать-вставлять) все свойства класса Model. в CustomersViewModel.

Испытание 1:

Я попытался сопоставить класс с самим собой, но у него возникли проблемы, связавшись со значениями внешнего ключа / отношениями базы данных - сообщение об ошибке выглядит как "Отношение не может быть изменено, потому что одно или несколько свойств внешнего ключа не могут иметь значение NULL"...". Затем я добавил.ForAllMembers(opt=>opt.Ignore()), и он стал еще хуже.

            Customers customers= db.Customers .SingleOrDefault(c => c.CustomerID == id);
        Customers editcustomers = AutoMapperMappings.mapper.Map<Customers , Customers >(customers);

Пробная версия 2: То, что я думал, было бы еще одним способом уйти без создания 14 частичных представлений и без вставки копий всех свойств с использованием automapper, что-то вроде этого

public class CustomersViewModel
{

    public Customers customers { get; set; }
}

затем карта и обратная карта

 cfg.CreateMap<CustomersViewModel, Customers>().ReverseMap();

GET контроллер

                Customers customers = db.Customers.SingleOrDefault(c => c.CustomerID == id);
        CustomerEditViewModel editcustomers = AutoMapperMappings.mapper.Map<Customers, CustomersEditViewModel>(customers);

        editcustomers.customers = customers;
return View(editcustomers);

тогда метод POST

Customers locate = db.Customers .Find(editcustomers.customers.customersID);

            AutoMapperMappings.mapper.Map(editcustomers.customers, locate);
            //locate = editcomponents.components;
            //db.Entry(locate).State = EntityState.Modified;
            db.SaveChanges(); 

но, несмотря на то, что отображение прошло успешно, без ошибок и GET загрузил представление, а POST получил измененные значения db.SaveChanges(); не получает измененные значения, обновление не происходит.

Но если скопировать все свойства из класса Model и скопировать их в ViewModel, сопоставление с помощью автоматического преобразователя сработает, и данные в представлении будут сохранены.

public class CustomersViewModel
{

    public int CustomerID { get; set; }
    public int InspectionID { get; set; }
    public int Position { get; set; }
    public Nullable<int> Height { get; set; }
    public Nullable<int> Weight{ get; set; }
    //...and all other properties 
}

У меня вопрос, есть ли способ сделать это с одной большой ViewModel без повторного перечисления всех свойств класса модели снова? Заранее большое спасибо за ваши предложения!

0 ответов

Другие вопросы по тегам