tags:

views:

42

answers:

1

I have a program with a base class (Message) from which many other classes derivate (notably Article and Comment). I would like to create a criteria that will select all the Comments for which the RootMessage property is of type Article (I have some other type of potential RootMessages). But I can't seem to find how to add that kind of constraint in a criteria.

For now my code is this:

 public virtual ICollection<Comment> GetCommentsByArticle(ISession session)
    {
        var c = session.CreateCriteria(typeof(Comment))
            .Add(Expression.Eq("Author", this))
            .AddOrder(Order.Desc("CreationDate"))
            .SetMaxResults(20);
        var commentList = c.List<Comment>();
        return commentList;

    }

But of course this returns every single comment of this Author. What I want is every single comment of this Author that have a RootMessage of the Article type.

These are the mappings.

Message:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               assembly="FolkeLib"
               namespace="Folke.Code.Domain">
<class name="Message" discriminator-value="0">
<id name="Id">
  <generator class="native"></generator>
</id>
<discriminator column="MessageType" type="Int32"/>
<timestamp column="ModificationDate" name="ModificationDate"/>
<property name="CreationDate" index="ArticleCreationDate"/>
<many-to-one name="Author"/>
<property name="Text" type="StringClob">
  <column name="Text" sql-type="text"/>
</property>
<property name="Locked"/>
<many-to-one name="Locker" not-null="false"/>
<many-to-one name="RootMessage" not-null="false"/>
<many-to-one name="ParentMessage" not-null="false"/>
<property name="Score"/>
<many-to-one name="Site" not-null="true"/>

Article:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               assembly="FolkeLib"
               namespace="Folke.Code.Domain">
<subclass name="Article" extends="Message" discriminator-value="1">
<property name="Title"/>
<set name="TagSet" lazy="true" table="MessageTag">
  <key column="MessageId"/>
  <many-to-many class="Tag" column="TagId"/>
</set>
<set name="ImageSet" lazy="true" table="MessageImage">
  <key column="MessageId"/>
  <many-to-many class="Image" column="ImageId"/>
</set>
<many-to-one name="Forum"/>
</subclass>
</hibernate-mapping>

Comment (class is pretty much empty for now):

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
               assembly="FolkeLib"
               namespace="Folke.Code.Domain">
  <subclass name="Comment" extends="Message" discriminator-value="2">
  </subclass>
</hibernate-mapping>

Any help appreciated!

+1  A: 

This would be easier to answer if you posted your complete mappings, but I believe something along the lines of:

.CreateAlias("RootMessage", "rm")
.Add(Expression.Eq("rm.class",typeof(Article))) 

Is what you're looking for.

DanP
I added the mappings to the OP as requested.
Whistle
NHibernate throws this error message:could not resolve property: RootMessage.class of: Folke.Code.Domain.CommentIt's looking for the property named "RootMessage.class" of the Comment, instead of the class of the Comment.RootMessage property.
Whistle
@Whistle: I think you may need to create an alias to do this properly, I have updated my answer to include this.
DanP
I no longer see the error message, but the result is the same as before: the comments show even if their RootMessage is not of the Article class.
Whistle
@Whistle: can you post the resulting sql?
DanP