Skip to content

NH-3482 - session.Quey().OfType().Count() is not translated to sql #1311

Open
@nhibernate-bot

Description

@nhibernate-bot

xumix created an issue — 14th June 2013, 13:25:56:

public class Order : EntityBase
{
    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Object"/> class.
    /// </summary>
    public Order(Guid id)
        : base(id)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Object"/> class.
    /// </summary>
    protected Order()
    {
    }

    public virtual DateTime OrderDate { get; set; }
    public virtual double Total { get; set; }
    public virtual string OrderType { get; set; }
    public virtual Customer Customer { get; set; }
}

public class OrderImpl : Order
{
    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Object"/> class.
    /// </summary>
    public OrderImpl(Guid id)
        : base(id)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Object"/> class.
    /// </summary>
    protected OrderImpl()
    {
    }

    public virtual string OrderType1 { get; set; }
}

public class OrderImplImpl : OrderImpl
{
    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Object"/> class.
    /// </summary>
    public OrderImplImpl(Guid id)
        : base(id)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.Object"/> class.
    /// </summary>
    protected OrderImplImpl()
    {
    }

    public virtual string OrderType2 { get; set; }
}

public NHibernate.ISessionFactory Create()
{
    var ret =
        Fluently
            .Configure()
            .Database(MsSqlConfiguration
                .MsSql2008
                .DoNot.UseOuterJoin()
                .UseReflectionOptimizer()
                .ShowSql()
                .FormatSql()
                .ConnectionString(ex =>
                    ex.FromConnectionStringWithKey("OrdersSqlServer")))
            .Mappings(
                x =>
                    x.AutoMappings.Add(
                        AutoMap.AssemblyOf<Order>(new AutoConfig()).UseOverridesFromAssemblyOf<Order>()
                            .Conventions.Add<DefaultStringLengthConvention>()
                            .Conventions.Add(DefaultCascade.None())))

            .ExposeConfiguration(config => new SchemaExport(config).Create(true, true))
            .BuildSessionFactory();

    return ret;
}

This works Ok

var or2 = session.Query<Order>().OfType<OrderImplImpl>().ToArray();

This fails

var or2 = session.Query<Order>().OfType<OrderImplImpl>().Count();

with

System.InvalidOperationException was unhandled by user code
  HResult=-2146233079
  Message=No coercion operator is defined between types 'System.Int32' and 'Orders.Domain.OrderImplImpl'.
  Source=System.Core
  StackTrace:
       at System.Linq.Expressions.Expression.GetUserDefinedCoercionOrThrow(ExpressionType coercionType, Expression expression, Type convertToType)
       at System.Linq.Expressions.Expression.Convert(Expression expression, Type type, MethodInfo method)
       at System.Linq.Expressions.Expression.Convert(Expression expression, Type type)
       at Remotion.Linq.Clauses.ResultOperators.OfTypeResultOperator.GetNewItemExpression(Expression inputItemExpression)
       at Remotion.Linq.Clauses.ResultOperators.OfTypeResultOperator.GetOutputDataInfo(IStreamedDataInfo inputInfo)
       at NHibernate.Linq.Visitors.QueryModelVisitor.VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, Int32 index)
       at Remotion.Linq.Clauses.ResultOperatorBase.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)
       at Remotion.Linq.QueryModelVisitorBase.VisitResultOperators(ObservableCollection`1 resultOperators, QueryModel queryModel)
       at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
       at NHibernate.Linq.Visitors.QueryModelVisitor.Visit()
       at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)
       at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory)
       at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)
       at NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
       at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
       at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)
       at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)
       at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
       at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
       at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
       at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
       at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)
       at System.Linq.Queryable.Count[TSource](IQueryable`1 source)
       at NHQS.Tests.MultipleDatabaseTests.sample_data_is_added_properly() in c:\Projects\NHibernate-QuickStart\NHQS.Tests\MultipleDatabaseTests.cs:line 85
  InnerException:

Ricardo Peres added a comment — 14th June 2013, 13:33:35:

Have you tried:

var or2 = session.Query().Where(x => x is OrderImplImpl).Count();


xumix added a comment — 14th June 2013, 13:44:26:

Yeah, and it is translated, thank you.
Some more data, this:

var or3 = session.Query().OfType().Select(c => c.Customer).ToArray();

gives this:
NHibernate.QueryException was unhandled by user code
HResult=-2146232832
Message=could not resolve property: class of: Orders.Domain.Customer <.Select[Orders.Domain.OrderImplImpl,Orders.Domain.Customer>(.OfType<Orders.Domain.OrderImplImpl>(NHibernate.Linq.NhQueryable1<Orders.Domain.Order>, ), Quote((c, ) => (c.Customer)), )] Source=NHibernate QueryString=.Select<Orders.Domain.OrderImplImpl,Orders.Domain.Customer>(.OfType<Orders.Domain.OrderImplImpl>(NHibernate.Linq.NhQueryable1<Orders.Domain.Order>, ), Quote((c, ) => (c.Customer)), )
StackTrace:
at NHibernate.Persister.Entity.AbstractPropertyMapping.ToType(String propertyName)
at NHibernate.Persister.Entity.AbstractEntityPersister.ToType(String propertyName)
at NHibernate.Hql.Ast.ANTLR.Tree.FromElementType.GetPropertyType(String propertyName, String propertyPath)
at NHibernate.Hql.Ast.ANTLR.Tree.FromElement.GetPropertyType(String propertyName, String propertyPath)
at NHibernate.Hql.Ast.ANTLR.Tree.DotNode.GetDataType()
at NHibernate.Hql.Ast.ANTLR.Tree.DotNode.PrepareLhs()
at NHibernate.Hql.Ast.ANTLR.Tree.DotNode.Resolve(Boolean generateJoin, Boolean implicitJoin, String classAlias, IASTNode parent)
at NHibernate.Hql.Ast.ANTLR.Tree.FromReferenceNode.Resolve(Boolean generateJoin, Boolean implicitJoin, String classAlias)
at NHibernate.Hql.Ast.ANTLR.Tree.FromReferenceNode.Resolve(Boolean generateJoin, Boolean implicitJoin)
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.Resolve(IASTNode node)
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.expr()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.exprOrSubquery()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.comparisonExpr()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.logicalExpr()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.whereClause()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.unionedQuery()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.query()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.selectStatement()
at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.statement()
at NHibernate.Hql.Ast.ANTLR.HqlSqlTranslator.Translate()
at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.Analyze(String collectionRole)
at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.DoCompile(IDictionary2 replacements, Boolean shallow, String collectionRole) at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.Compile(IDictionary2 replacements, Boolean shallow)
at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, IDictionary2 filters, ISessionFactoryImplementor factory) at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary2 filters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary2 enabledFilters, ISessionFactoryImplementor factory) at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary2 enabledFilters, ISessionFactoryImplementor factory)
at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, Boolean shallow, IDictionary2 enabledFilters, ISessionFactoryImplementor factory) at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary2 enabledFilters)
at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)
at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)
at NHibernate.Linq.DefaultQueryProvider.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)
at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)
at Remotion.Linq.QueryableBase1.GetEnumerator() at System.Linq.Buffer1..ctor(IEnumerable1 source) at System.Linq.Enumerable.ToArray<TSource>(IEnumerable1 source)
at NHQS.Tests.MultipleDatabaseTests.sampledata_is_addedproperly() in c:\Projects\NHibernate-QuickStart\NHQS.Tests\MultipleDatabaseTests.cs:line 86
InnerException:


xumix added a comment — 14th June 2013, 13:45:24:

var or = session.Query().Select(c => c.Customer).ToArray(); - this works flawlessly


Ricardo Peres added a comment — 14th June 2013, 14:01:32:

The message "property class does not exist" is issued whenever there is no inheritance defined. For example, in HQL, the following query works if there is an hierarchy of classes, ConcreteClass inherits from BaseClass:

"from BaseClass c where c.class = ConcreteClass"

And if you try it without the hierarchy, it fails.
I do not know Fluent NHibernate, are you sure the inheritance is being mapped - that is, not the classes individually, but their inheritance?


xumix added a comment — 14th June 2013, 14:11:36:

var or4 = session.Query().Select(c => c.Customer).ToArray(); - works as intended

Gives me this sql:

SELECT customer1*.Id AS Id1* ,
customer1*.FirstName AS FirstName1* ,
customer1*.LastName AS LastName1*
FROM OrderImplImpl orderimpli0_
INNER JOIN OrderImpl orderimpli01_ ON orderimpli0_.OrderImpl_id = orderimpli0_1_.Orderid
INNER JOIN orderimpli02_ ON orderimpli0_.OrderImpl_id = orderimpli0_2.Id
LEFT OUTER JOIN [Customer] customer1* ON orderimpli0_2_.Customer_id = customer1*.Id

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions