Search code examples
fluent-nhibernatenhibernate-mapping

FluentNHibernate: Nested component mapping results in NHiberate QueryException


Hi i have a problem with mapping in Nhibernate. When I run a linq query referring to one of the component classes of my entity, I get a QueryException as below:

could not resolve property: ClosedCases of: Project.Entities.Headline

I have one table with records which i want to map into multiple objects of my headline entity.

Question:

Is there something wrongly set up in my mapping?

My Headline entity is separated into multiple logical classes as you can see below

  public class Headline:Entity
  {
    public virtual DateTime Date { get; set; }
    public virtual TeamTarget Teamtarget { get; set; }
  } 

 public class TeamTarget : Entity
  {
    public virtual DateTime FromDate { get; set; }
    public virtual DateTime ToDate { get; set; }
    public virtual TargetItem AchievedTarget { get; set; }
    public virtual Team Team { get; set; }
    }  

public class TargetItem : Entity
  {
    public virtual decimal ClosedCases { get; set; }
    public virtual decimal Invoicing { get; set; }
  }

Mapping file:

  public class HeadlineMap: ClassMap<Headline>
  {
    public HeadlineMap()
    {
      Table("Headlines.Headlines");
      Id(x => x.Id).Column("HeadlinesId");
      Map(x => x.Date);
      Component(x => x.Teamtarget, t =>
      {
        t.References(x => x.Team).Column("TeamId").Cascade.None();
        t.Component(x => x.AchievedTarget, ti =>
        {
          ti.Map(x => x.Invoicing).Column("TeamInvoicing");
          ti.Map(x => x.ClosedCases).Column("TeamClosedCases");
        });
      });

The Linq query I am running looks like this:

decimal closedCases = _headlineRepository.All
.Where(x =>
x.Date >= DateTimeExtensionMethods.FirstDayOfMonthFromDateTime(selectMonthFromDate)
&& x.Date <= DateTimeExtensionMethods.LastDayOfMonthFromDateTime(selectMonthFromDate)
&& x.Teamtarget.Team.Id == teamId
).Average(x => x.Teamtarget.AchievedTarget.ClosedCases);

I know that i can access headline item by using team entity by team id and this works, just have problem with the mapping of achieved target. any ideas?


Solution

  • I think your mapping is fine. But as far as I know, it isn't possible to query a nested component with Linq to NHibernate. It can't understand what joins to do, it becomes too complex.

    I think it is possible using NHibernate 3's QueryOver API using JoinQueryOver or JoinAlias. You should read this: QueryOver in NH 3.0

    Maybe something like this would work:

    Headline headlineAlias = null;
    TeamTarget targetAlias = null;
    Team teamAlias = null;
    TargetItem targetItemAlias = null;
    
    var query = session.QueryOver<Headline>(() => headlineAlias)
                       .JoinAlias(() => headlineAlias.Teamtarget, () => targetAlias)
                       .JoinAlias(() => targetAlias.Team, () => teamAlias)
                       .JoinAlias(() => targetAlias.AchievedTarget, () => targetItemAlias)
                       .Where(x => x.Date >= DateTimeExtensionMethods.FirstDayOfMonthFromDateTime(selectMonthFromDate) && x.Date <= DateTimeExtensionMethods.LastDayOfMonthFromDateTime(selectMonthFromDate))
                       .And(() => teamAlias.Id == teamId)
                       .Select(Projections.Avg(() => targetItemAlias.ClosedCases))
                       .SingleOrDefault<decimal>();