2013-04-30 16 views
7

Jestem nowy w ASP.net MVC i używam viewmodel, a nie viewbags, aby wypełnić moje listy rozwijane, ponieważ widziałem, jak większość ludzi poleca przeciwko nim. Mam sprytny interfejs użytkownika, który powoduje kaskadowanie rozwijanych i autouzupełniania (nie pokazano tutaj), ale nie mogę przywrócić danych do bazy danych.Zapisywanie danych Viewmodel do bazy danych w ASP.NET MVC

Modele:

public partial class Car 
    { 
     public int CarID { get; set; } 
     public string CarName { get; set; } 
     public int ModelID { get; set; } 
     public int ManufacturerID { get; set; } 
     public int CarColorID { get; set; } 
     public Nullable<decimal> Price { get; set; } 
     public string Description { get; set; } 

     public virtual CarColor CarColor { get; set; } 
     public virtual Manufacturer Manufacturer { get; set; } 
     public virtual CarModel CarModel { get; set; } 
    } 
    public partial class CarColor 
    { 
     public CarColor() 
     { 
      this.Cars = new HashSet<Car>(); 
     } 

     public int ColorID { get; set; } 
     public string ColorName { get; set; } 

     public virtual ICollection<Car> Cars { get; set; } 
    } 
    public partial class CarModel 
    { 
     public CarModel() 
     { 
      this.Cars = new HashSet<Car>(); 
     } 

     public int CarModelID { get; set; } 
     public int ManufacturerID { get; set; } 
     public string CarModelName { get; set; } 

     public virtual ICollection<Car> Cars { get; set; } 
     public virtual Manufacturer Manufacturer { get; set; } 
    } 
    public partial class Manufacturer 
    { 
     public Manufacturer() 
     { 
      this.Cars = new HashSet<Car>(); 
      this.Manufacturer1 = new HashSet<Manufacturer>(); 
      this.CarModels = new HashSet<CarModel>(); 
     } 

     public int ManufacturerID { get; set; } 
     public string ManufacturerName { get; set; } 
     public Nullable<int> ParentID { get; set; } 

     public virtual ICollection<Car> Cars { get; set; } 
     public virtual ICollection<Manufacturer> Manufacturer1 { get; set; } 
     public virtual Manufacturer Manufacturer2 { get; set; } 
     public virtual ICollection<CarModel> CarModels { get; set; } 
    } 

ViewModel:

Kontroler:

public ActionResult Create() 
     { 
      var model = new AnotherTestViewModel(); 
      using (new CarTestEntities()) 
      { 
       model.CarModels = db.CarModels.ToList().Select(x => new SelectListItem 
       { 
        Value = x.CarModelID.ToString(), 
        Text = x.CarModelName 
       }); 
       model.Manufacturers = db.Manufacturers.ToList().Select(x => new SelectListItem 
       { 
        Value = x.ManufacturerID.ToString(), 
        Text = x.ManufacturerName 
       }); 
       model.CarColors = db.CarColors.ToList().Select(x => new SelectListItem 
       { 
        Value = x.ColorID.ToString(), 
        Text = x.ColorName 
       }); 
      } 
      return View(model); 
     } 

     // 
     // POST: /AnotherTest/Create 

     [HttpPost] 
     public ActionResult Create(AnotherTestViewModel model) 
     { 
       if (ModelState.IsValid) 
       { 
        db.Entry(model).State = EntityState.Modified; 
        db.SaveChanges(); 
        return RedirectToAction("Details", "AnotherTestViewModel", new { id = model.car.CarID }); 
       } 
       return View(); 
     } 

Widziałem kilka zaleceń do korzystania Automapper ponieważ EntityState.Modified nie będzie działać, ale nie jestem pewien jak to skonfigurować, ponieważ użycie poniższego kodu nie zadziałało.

Mapper.CreateMap<AnotherTestViewModel, Car>(); 
Mapper.CreateMap<Car, AnotherTestViewModel>(); 
var newCar = Mapper.Map<AnotherTestViewModel, Car>(model); 

Wszelkie pomysły?

Odpowiedz

21

Twój model widoku nie powinien wchodzić w interakcje z bazą danych. Modele widoku powinny być używane tylko w warstwie prezentacji (interfejsie użytkownika) - stąd nazwa "Widok". Powinieneś mieć inny model (model danych), który współdziała z twoją bazą danych. Następnie powinieneś mieć warstwę serwisową, która obsługuje konwersję między modelem widoku a modelem danych (i na odwrót). Twój model danych to model wygenerowany przez Entity Framework (który, jak zakładam, jest tym, czego używasz). Aby obsłużyć aktualizacje bazy danych, należy utworzyć instancję danych, pobrać jednostkę danych z bazy danych, wprowadzić zmiany w tej jednostce i wywołać wszystkie zmiany zapisu w tym kontekście danych. Kontekst danych będzie śledzić wszystkie zmiany w Twoich jednostkach i wprowadzać niezbędne zmiany do bazy danych, gdy wywołasz "Zapisz zmiany". przykład:

public void UpdateCar(CarViewModel viewModel) 
{ 
    using (DataContext context = new DataContext()) 
    { 
     CarEntity dataModel = context.CarEntities.where(x => x.Id == viewModel.Id).First(); 

     dataModel.Name = viewModel.Name; 
     dataModel.Type = viewModel.Type; 

     context.SaveChanges(); 
    } 
} 

W przykładzie tym kontekście będzie śledzić wszelkie zmiany „dataModel”. Po wywołaniu "context.SaveChanges" zmiany te zostaną automatycznie zastosowane do bazy danych.

+0

Dziękuję bardzo! Takiej właśnie pomocy potrzebowałem. – Jim

+0

Gdzie działa ta funkcja "UpdateCar"? Mówisz w jakiejś "Warstwie usług", czy możesz być dokładniejszy? Dzięki! – crunchy

+0

Usługa faktycznie nie powinna nic wiedzieć na temat interfejsu użytkownika. Tak więc ta konwersja do twojej domeny/modelu danych powinna zostać wykonana w kontrolerze. Następnie przekazujesz model domeny/danych do metody warstwy usług, która wykonuje aktualizację. – RiceRiceBaby

Powiązane problemy