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.