2012-06-29 134 views
3

爲了創建一個更優雅的解決方案,我很好奇知道您關於持久化集合的解決方案的建議。MVC Persist Collection ViewModel(更新,刪除,插入)

我有一個存儲在數據庫上的集合。 此集合轉到視圖模型的網頁中。 當從網頁返回到控制器時,我需要將修改後的集合持久化到同一個數據庫。

簡單的解決方案是刪除存儲的集合並重新創建所有行。 我需要一個更優雅的解決方案來混合集合並刪除不存在的記錄,更新相似的記錄並插入新行。

這是我的Models和ViewModels。

public class CustomerModel 
{ 
    public virtual string Id { get; set; } 
    public virtual string Name { get; set; } 

    public virtual IList<PreferredAirportModel> PreferedAirports { get; set; } 
} 

public class AirportModel 
{ 
    public virtual string Id { get; set; } 
    public virtual string AirportName { get; set; } 
} 

public class PreferredAirportModel 
{ 
    public virtual AirportModel Airport { get; set; } 
    public virtual int CheckInMinutes { get; set; } 
} 

// ViewModels 
public class CustomerViewModel 
{ 
    [Required] 
    public virtual string Id { get; set; } 
    public virtual string Name { get; set; } 

    public virtual IList<PreferredAirporViewtModel> PreferedAirports { get; set; } 
} 

public class PreferredAirporViewtModel 
{ 
    [Required] 
    public virtual string AirportId { get; set; } 

    [Required] 
    public virtual int CheckInMinutes { get; set; } 
} 

而這是控制器沒有優雅的解決方案。

public class CustomerController 
{ 
    public ActionResult Save(string id, CustomerViewModel viewModel) 
    { 
     var session = SessionFactory.CurrentSession; 

     var customer = session.Query<CustomerModel>().SingleOrDefault(el => el.Id == id); 

     customer.Name = viewModel.Name; 

     // How can I Merge collections handling delete, update and inserts ? 

     var modifiedPreferedAirports = new List<PreferredAirportModel>(); 
     var modifiedPreferedAirportsVm = new List<PreferredAirporViewtModel>(); 

     // Update every common Airport 
     foreach (var airport in viewModel.PreferedAirports) 
     { 
      foreach (var custPa in customer.PreferedAirports) 
      { 
       if (custPa.Airport.Id == airport.AirportId) 
       { 
        modifiedPreferedAirports.Add(custPa); 
        modifiedPreferedAirportsVm.Add(airport); 

        custPa.CheckInMinutes = airport.CheckInMinutes; 
       } 
      } 
     } 

     // Remove common airports from ViewModel 
     modifiedPreferedAirportsVm.ForEach(el => viewModel.PreferedAirports.Remove(el)); 

     // Remove deleted airports from model 
     var toDelete = customer.PreferedAirports.Except(modifiedPreferedAirports); 
     toDelete.ForEach(el => customer.PreferedAirports.Remove(el)); 

     // Add new Airports 
     var toAdd = viewModel.PreferedAirports.Select(el => new PreferredAirportModel 
                  { 
                   Airport = 
                      session.Query<AirportModel>(). 
                      SingleOrDefault(a => a.Id == el.AirportId), 
                   CheckInMinutes = el.CheckInMinutes 
                  }); 
     toAdd.ForEach(el => customer.PreferedAirports.Add(el)); 

     session.Save(customer); 

     return View(); 
    } 
} 

我的環境是ASP.NET MVC 4,nHibernate,Automapper,SQL Server。

回答

2

那麼,如果 「優雅」 只不過是 「不明確和重建」 的報告(未經測試):

var airports = customer.PreferedAirports; 
var viewModelAirports = viewModel.PreferredAirports; 

foreach (var airport in airports) { 
    //modify common airports 
    var viewModelAirport = viewModelAirports.FirstOrDefault(m => m.AirportId == airport.AirportId); 
    if (viewModelAirport != null) { 
     airport.X = viewModelAirport.X; 
     airport.Z = viewModelAirport.Z; 
     //remove commonAirports from List 
     viewModelAirports.Remove(viewModelAirport); 
     continue; 
    } 
    //delete airports not present in ViewModel 
    customer.PreferedAirports.Remove(airport); 
} 

//add new airports 
foreach (var viewModelAirport in viewModelAirports) { 
    customer.PreferedAirports.Add(new PreferredAirportModel { 
      Airport = session.Query<AirportModel>().SingleOrDefault(a => a.Id == el.AirportId), 
      CheckInMinutes = el.CheckInMinutes 
      }); 
} 
session.Save(customer);