Hello everybody,

here is my domain (all the entities' ids are GUID)

class User { ... }
class Contact { ... }
abstract class MessageSender { String Label { ... } }
class UserSender : MessageSender { User User { ... } }
class ContactSender : MessageSender { Contact Contact { ... } }
class NullSender : MessageSender {  }
class Message { MessageSender Sender { ... } }

and the (relevant) mapping using NHibernate 3.0.0.4:

<class name="Message" table="Message">
    <id name="Id" column="Id"> <class="guid"/></id>
    <many-to-one name="Sender" column="Sender" class="MessageSender"
not-null="false"/>
  </class>
<class name="MessageSender" table="MessageSender"
         abstract="true" polymorphism="implicit">
    <id name="Id" column="Id">
      <generator class="guid"/>
    </id>
    <property name="Label" column="Label"/>
  </class>
  <joined-subclass name="NullSender" extends="MessageSender" abstract="false">
    <key column="Id"/>
  </joined-subclass>
  <joined-subclass name="UserSender" extends="MessageSender" abstract="false">
    <key column="Id"/>
    <many-to-one name="User" class="User" column="UserId" not-null="true"/>
  </joined-subclass>
  <joined-subclass name="ContactSender" extends="" abstract="false">
    <key column="Id"/>
    <many-to-one name="Contact" class="Contact" column="ContactId"
not-null="true"/>
  </joined-subclass>

#FIRST PROBLEM#
ISessionFactory sf = ...;
using (var s = sf.OpenSession())
{
    s.Query<MailMessage>().Where(m => m.Sender is NullSender).ToList();
}

using (var s = sf.OpenSession())
{
    s.Query<MailMessage>().Where(m => m.Sender is UserSender).ToList();
}

Here is the generated SQL code:

select message0_.Id as Id0_, message0_.Sender as Sender0_ from Message
message0_, MessageSender sender1_ left outer join NullSender
sender1_1_ on sender1_.Id=sender1_1_.Id left outer join UserSender
sender1_2_ on sender1_.Id=sender1_2_.Id left outer join ContactSender
sender1_3_ on sender1_.Id=sender1_3_.Id where
message0_.Sender=sender1_.Id and case when sender1_1_.Id is not null
then 1 when sender1_2_.Id is not null then 2 when sender1_3_.Id is not
null then 3 when sender1_.Id is not null then 0 end=1

select message0_.Id as Id0_, message0_.Sender as Sender0_ from Message
message0_, MessageSender sender1_ left outer join NullSender
sender1_1_ on sender1_.Id=sender1_1_.Id left outer join UserSender
sender1_2_ on sender1_.Id=sender1_2_.Id left outer join ContactSender
sender1_3_ on sender1_.Id=sender1_3_.Id where
message0_.Sender=sender1_.Id and case when sender1_1_.Id is not null
then 1 when sender1_2_.Id is not null then 2 when sender1_3_.Id is not
null then 3 when sender1_.Id is not null then 0 end=1

i.e.: the code is THE SAME for both the queries, so I always get all
those messages having m.Sender of NullSender type.

#SECOND PROBLEM#
Somewhere in my application I have to select all those messages for a
given MessageSender set, but solutions like:

ISession s = ...;
var senders = s.Query<MessageSender>().Where(s => s.Label.Contains("xyz");
var messages = s.Query<Message>().Join(senders, msg => msg.Sender,
sender => sender, (msg, sender) => msg).ToList();

always raise a NotSupportedException.

System.Linq.IQueryable`1[MessageSender]
Where[MessageSender](System.Linq.IQueryable`1[MessageSender],
System.Linq.Expressions.Expression`1[System.Func`2[MessageSender,System.Boolean]])

   at 
NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitMethodCallExpression(MethodCallExpression
expression) in 
d:\CSharp\NH\nhibernate\src\NHibernate\Linq\Visitors\HqlGeneratorExpressionTreeVisitor.cs:line
396
   at 
NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.VisitExpression(Expression
expression) in 
d:\CSharp\NH\nhibernate\src\NHibernate\Linq\Visitors\HqlGeneratorExpressionTreeVisitor.cs:line
94
   at 
NHibernate.Linq.Visitors.HqlGeneratorExpressionTreeVisitor.Visit(Expression
expression, VisitorParameters parameters) in
d:\CSharp\NH\nhibernate\src\NHibernate\Linq\Visitors\HqlGeneratorExpressionTreeVisitor.cs:line
21
   at NHibernate.Linq.Visitors.QueryModelVisitor.VisitJoinClause(JoinClause
joinClause, QueryModel queryModel, Int32 index) in
d:\CSharp\NH\nhibernate\src\NHibernate\Linq\Visitors\QueryModelVisitor.cs:line
177
   at Remotion.Data.Linq.Clauses.JoinClause.Accept(IQueryModelVisitor
visitor, QueryModel queryModel, Int32 index)
   at 
Remotion.Data.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection`1
bodyClauses, QueryModel queryModel)
   at Remotion.Data.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel
queryModel)
   at NHibernate.Linq.Visitors.QueryModelVisitor.Visit() in
d:\CSharp\NH\nhibernate\src\NHibernate\Linq\Visitors\QueryModelVisitor.cs:line
96
   at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel
queryModel, VisitorParameters parameters, Boolean root) in
d:\CSharp\NH\nhibernate\src\NHibernate\Linq\Visitors\QueryModelVisitor.cs:line
49
   at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor
sessionFactory) in
d:\CSharp\NH\nhibernate\src\NHibernate\Linq\NhLinqExpression.cs:line
67
   at 
NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String
queryIdentifier, IQueryExpression queryExpression, String
collectionRole, Boolean shallow, IDictionary`2 filters,
ISessionFactoryImplementor factory) in
d:\CSharp\NH\nhibernate\src\NHibernate\Hql\Ast\ANTLR\ASTQueryTranslatorFactory.cs:line
27
   at NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String
expressionStr, IQueryExpression queryExpression, String
collectionRole, Boolean shallow, IDictionary`2 enabledFilters,
ISessionFactoryImplementor factory) in
d:\CSharp\NH\nhibernate\src\NHibernate\Engine\Query\HQLExpressionQueryPlan.cs:line
34
   at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String
expressionStr, IQueryExpression queryExpression, String
collectionRole, Boolean shallow, IDictionary`2 enabledFilters,
ISessionFactoryImplementor factory) in
d:\CSharp\NH\nhibernate\src\NHibernate\Engine\Query\HQLExpressionQueryPlan.cs:line
23
   at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String
expressionStr, IQueryExpression queryExpression, Boolean shallow,
IDictionary`2 enabledFilters, ISessionFactoryImplementor factory) in
d:\CSharp\NH\nhibernate\src\NHibernate\Engine\Query\HQLExpressionQueryPlan.cs:line
17
   at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression
queryExpression, Boolean shallow, IDictionary`2 enabledFilters) in
d:\CSharp\NH\nhibernate\src\NHibernate\Engine\Query\QueryPlanCache.cs:line
88
   at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression
queryExpression, Boolean shallow) in
d:\CSharp\NH\nhibernate\src\NHibernate\Impl\AbstractSessionImpl.cs:line
302
   at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression
queryExpression) in
d:\CSharp\NH\nhibernate\src\NHibernate\Impl\AbstractSessionImpl.cs:line
258
   at NHibernate.Linq.NhQueryProvider.PrepareQuery(Expression
expression, IQuery& query, NhLinqExpression& nhQuery) in
d:\CSharp\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs:line 42
   at NHibernate.Linq.NhQueryProvider.Execute(Expression expression)
in d:\CSharp\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs:line
25
   at NHibernate.Linq.NhQueryProvider.Execute[TResult](Expression
expression) in 
d:\CSharp\NH\nhibernate\src\NHibernate\Linq\NhQueryProvider.cs:line
102
   at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
   at MappingsTest.GetMessageBySender() in ...

Any hint? Am I wrong or I'm dealing with some NH's linq provider bugs?

Thanks in advance,
Giulio

--

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to