Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most elegant way to update a child collection when using nhibernate (without creating unnecessary adds and deletes)?

I have an domain object called Project which maps to a table in my SQL server database. It has a property that is a List called Dependencies.

   public class Project
   {
         public int Id;
         public List<ProjectDependency> Dependencies;   
   }

   public class ProjectDependency
   {
          public Project Project;
          public Project Dependency;
   }

and and I trying to figure out the most efficient way to update the list of dependencies given a new list of dependencyIds.

So here is a naive implementation:

 public void UpdateDependencies(Project p, List<int> newDependencyIds)
 {
       p.Dependencies.Clear();
       foreach (var dependencyId in newDependencyIds)
       {
             Project d = GetDependency(dependencyId)
             p.Dependencies.Add(new ProjectDependency{Project = p, Dependency = d});
       }
 }

but the issue here is that even if nothing changes, I am clearing out all items and doing inserts on the same items that were there before.

I am looking for an elegant way to determine the diff (whats been added, whats been removed) and just make those changes so if a dependency was there before and after then it doesn't get touched.

like image 347
leora Avatar asked Jun 19 '14 04:06

leora


People also ask

What is bag in NHibernate?

A bag is an unordered, unindexed collection which may contain the same element multiple times. The . NET collections framework lacks an IBag interface, hence you have to emulate it with an IList. NHibernate lets you map properties of type IList or ICollection with the <bag> element.

Does NHibernate use ADO Net?

NHibernate relies on the ADO.NET data provider implementation of connection pooling.


1 Answers

    public void UpdateDependencies(Project p, List<int> newDependencyIds)
    {
        p.Dependencies.RemoveAll(d => !newDependencyIds.Contains(d.Dependency.Id));
        var toAdd = newDependencyIds.Select(d => p.Dependencies.Any(pd => pd.Dependency.Id != d)).ToList();
        toAdd.ForEach(dependencyId => p.Dependencies.Add(new ProjectDependency{Project = p, Dependency = GetDependency(dependencyId)}));
    }
like image 163
Low Flying Pelican Avatar answered Oct 24 '22 14:10

Low Flying Pelican