Search code examples
c#nhibernatefluent-nhibernatequeryover

QueryOver using an ignored property


I have two entities:

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

public class Child
{
    public virtual int Id { get; set; }
    public virtual int ParentId 
    { 
        get
        {
            if (Parent != null)
                return Parent.Id;
            return -1;
        }

        set
        {
            if (Parent != null)
                Parent = new Parent();
            Parent.Id = value;
        } 
    }

    protected virtual Parent Parent
    {
        get;
        set;
    }
}

The Parent property is set up like this to simplify the API side, and I do not want to change it to expose this property publicly. I have an override of the mappings for the Child class to accommodate this:

public class ChildMappingOverrides : IAutoMappingOverride<Child>
{
    public void Override(AutoMapping<Child> mapping)
    {
        mapping.References<Parent>(Reveal.Member<Child>("Parent")).Column("Parent_id");
        mapping.IgnoreProperty(x => x.ParentId);
    }
}

Now, if I want to query all the Child objects for a given parent Id, I would perform this:

session.QueryOver<Child>().Where(c => c.ParentId == 1);

However, this throws a QueryException:

could not resolve property: ParentId of: My.Namespace.Child

How can I retrieve the set of Child objects that have a particular Parent Id?


Solution

  • Untested, but you could try this:

    session.QueryOver<Child>()
        .Where(Restrictions.Eq(
            Projections.SqlProjection(
                "{alias}.Parent_id as ParentId",
                new[] { "ParentId" },
                new[] { NHibernateUtil.Int32 }), 1))
        .List<Child>();
    

    You're not going to be able to query on unmapped associations in any NHibernate query, but this at least minimizes the loss of compile-time checking.

    This is somewhat limited from what I can tell. {alias} will always be replaced by the alias of the root entity, meaning if you want to do this for a more complex query that doesn't start with Child, you might be out of luck.