1

I am trying in my Service Layer to return a Parent that has a collection of Child objects that I need filtered. Only the child objects are filtered so even if the filter means 0 child objects the Parent object is still returned.

As you can see from the below code the method I'm trying to use here is very simple. I've looked into other SO questions that seem similar but have yet to get the answer.

  • I don't require the filter to occur at the database query, altho if that is possible it would be ok.
  • If using a single LINQ statement then filtering all child objects should still return the Parent (Project).

I know this can be solved by adding a WHERE clause to the Mapping but this does let you cascade deletes.

When using the below code the following exception is thrown:

A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: Project.Properties

// Entities

 public class Project
 {
   public virtual int Id { get; set; }

   private ICollection<Property> properties = new List<Property>();

   public virtual ICollection<Property> Properties
   {
      get { return properties; }
      set { properties = value; }
   }
 }

public class Property
{
  public virtual DateTime? DateDeleted { get; set; }
}

// Fluent NHibernate Mapping

  mapping.HasMany<Property>(x => x.Properties)
      .ForeignKeyConstraintName("Project_Id")
      .AsSet()
      .Cascade.AllDeleteOrphan()
      .OrderBy("Estate_Id");

// Service Layer: call project repository. only return project with active properties

private ProjectDto GetActiveProject(int id)
{
    var p = projectRepository.Get(id);

    //filter out deleted properties
    if (p != null)
        p.Properties = p.Properties.Where(x => x.DateDeleted == null).ToList();

    return projectTransformer.Transform(p);
}
Galen
  • 309
  • 1
  • 3
  • 15

2 Answers2

1

As the exception message says, you are not allowed to replace a collection that is mapped with cascade="all-delete-orphan", so don't assign anything to p.Properties. This is because NHibernate needs its special collection class to know what childs were removed.

I think you have two possibilities:

  1. Create a property in the Project class that returns the filtered collection (but doesn't modify the actual Properties collection) and use this property everywhere you need the filtered data.
  2. Use NHibernate filters. See here.
cremor
  • 6,669
  • 1
  • 29
  • 72
1

There is a great answer here on SO. However it uses Criteria rather than Linq

Basically filters are your friend here.

Community
  • 1
  • 1
Rippo
  • 22,117
  • 14
  • 78
  • 117