2012-06-29 136 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);