Inheritance Mapping Fluent NHibernate results in unnecessary joins

Viewed 29

The issue is when selecting directly on the base model the generated SQL performs an left outer select on the subclasses.

Basemodel.

public class Node
{
   public virtual int ID {get;set;}
   public virtual string Url {get;set;}
}

public class CMSPage : Node
{
   public virtual string FieldA {get;set;}
   public virtual string FieldB {get;set;}
}

public class Article : Node 
{
   public virtual string FieldC {get;set;}
   public virtual string FieldD {get;set;}
}

My Mapping is

public class NodeMap : ClassMap<Node>
{
   Table("Nodes");
   Id(x => x.ID, "Node_ID");
   Map(x => x.Url);
}    

public class CMSPageMap: SubclassMap<CMSPage>
{
   Table("CMSPages");
   Map(x => x.FieldA);
   Map(x => x.FieldB);
}    

public class ArticleMap: SubclassMap<Article>
{
   Table("Articles");
   Map(x => x.FieldC);
   Map(x => x.FieldD);
}    

When querying direct on Nodes using ICriteria

  var store = session.CreateCriteria(typeof(Node));           
  store.Add(Restrictions.Eq("Url", filter.Url));                
  store.SetProjection(Projections.ProjectionList()
   .Add(Projections.Property("ID"), "ID")                   
   .Add(Projections.Property("Url"), "Url"));                
  store.SetResultTransformer(new 
  AliasToBeanResultTransformer(typeof(Node)));
  Node result = store.UniqueResult<Node>();

The sql generated is

SELECT this_.Node_ID     as y0_, this_.Url         as y7_ FROM   Nodes this_
   left outer join CMSPages this_1_
   on this_.Node_ID = this_1_.Node_ID
   left outer join Articles this_2_
   on this_.Node_ID = this_2_.Node_ID
WHERE  this_.Url = '/' /* @p0 - Url */

How do i prevent the join selects

Ive tried using both Abstract and KeyColumn according to https://www.codeproject.com/Articles/232034/Inheritance-mapping-strategies-in-Fluent-Nhibernat

1 Answers

Subclass mapping purpose is to have a Table per class hierarchy. Means you have one table for any child class. You can find examples on the documentation about all kind of supported inheritance by NHibernate.

I think you need to try "Table per subclass" strategy, using a JoinedSubclassMap<T>. The two subclass tables have primary key associations to the superclass table so the relational model is actually a one-to-one association. Documentation 9.1.2. Table per subclass

If you want to keep the SubclassMap<T> you must use a discriminator. 9.1.3. Table per subclass, using a discriminator.

Related