3

为了创建一个更优雅的解决方案,我很想知道您对持久化集合的解决方案的建议。

我有一个存储在 DB 上的集合。此集合转到视图模型中的网页。当从网页返回到控制器时,我需要将修改后的集合保存到同一个数据库中。

简单的解决方案是删除存储的集合并重新创建所有行。我需要一个更优雅的解决方案来混合集合并删除不存在的记录,更新类似记录并插入新行。

这是我的模型和视图模型。

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。

4

1 回答 1

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);
于 2012-06-29T13:15:05.423 回答