tags:

views:

41

answers:

3

I have a class Child which does not have a ParentId property but has the required foreign key in the database. I am trying to get the Children using the ParentId using NHibernate but it is throwing an error saying that could not resolve property ParentId.

public class Parent
{
     public int ParentId{ get; set; }

     public string Name{ get; set; }
}

public class Child
{
     public int ChildId{ get; set; }

     public string Name{ get; set; }
}

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="SomeAssembly"
                   namespace="SomeAssembly.SomeNamespace">
    <class name="Parent" lazy="false" table="Parents">
        <id name="ParentId">
            <generator class="native" />
        </id>
        <property name="Name" />
    </class>

    <class name="Child" lazy="false" table="Children">
        <id name="ChildId">
            <generator class="native" />
        </id>
        <property name="Name" />
    </class>
</hibernate-mapping>
+1  A: 

If you don't want to have a ParentId property, you should ad a private field ParentId, then you can still query it, but it's not public, so it's not visible to the rest of your application.

dmonlord
The model is already developed and I cannot change it.
Hemanshu Bhojak
The public api will not change if you take dmnonlord suggestion. So this is one possible solution.
mynkow
I have a dll reference to the model and cannot change it. Otherwise it would have been an easier task :(
Hemanshu Bhojak
still, you can inherit the model class and add private field, add mapping for it and you'll basically home free.But if the model is wrong it should be changed. If you can't do it you should talk to the guy who can.An alternative is that you use CreateSQLQuery as suggested by Jamie Ide.
dmonlord
Instead of programming against an awkward model at all, would it be better to program against a wrapper? You can inherit from the original model, or you could delegate to it. If you delegate, use component mapping (http://ayende.com/Blog/archive/2009/04/08/nhibernate-mapping-ltcomponentgt.aspx), where the underlying model is the component, and your custom wrapper is the class that is mapped against.
apollodude217
+1  A: 

Use a Native SQL Query:

return session.CreateSQLQuery("select * from ChildTable where ParentId = ?")
    .AddEntity(typeof(Child))
    .SetInt32(0, parentId)
    .UniqueResult<Child>();
Jamie Ide
SQL queries are a last resort as they do away with (at least) one of the major benefits of using NHibernate at all.
apollodude217
Every real world non-trivial NHibernate application has a few edge, legacy, or performance-driven cases where using SQL is necessary and appropriate. Direct SQL queries are a specialized tool that should be used sparingly, but I wouldn't characterize them as a "last resort."
Jamie Ide
+1  A: 

To use a column with NHibernate without a property in your domain class, use can use the lesser-known noop access: http://ayende.com/Blog/archive/2009/06/10/nhibernate-ndash-query-only-properties.aspx.

Something like this (haven't tried it myself):

<property name="ParentId" access="noop" />

I bet you could make this more slick by mapping a many-to-one of type Parent instead.

apollodude217