Skip to content

Invalid parameter conversion with group by #2693

Closed
@xnovak11

Description

@xnovak11

Invalid parameter conversion for enums parameters in Linq queries with GROUP BY and CASE statement in NHibernate 5.3.
In some scenarios are enum parameters convert as int instead of nvarchar.
Most probably related to 2439 and 2649

One of our scenario failed after upgrade from 5.2.6 to 5.3.5. It is still failing after upgrade to 5.3.6.

Here is simplified example:

public enum InvoiceType
{
      INCOME,
      OUTCOME
}

public class Invoice
{
      public virtual InvoiceType InvoiceType {get;set;}
      public virtual DateTime Date {get;set;}
}

public class InvoiceItem
{
      public virtual long ItemTypeid {get;set;}
      public virtual decimal Price {get;set;}
      public virtual Invoice Invoice {get;set;}
}

Failing query:

Session.Query<InvoiceItem>()
    .Where(it=> it.Invoice.Date >= new DateTime(2021,1,1))
    .GroupBy(it =>
         new
         {
             ItemTypeId = it.ItemTypeId,
             InvoceType = it.Invoice.InvoiceType
         }) 
    .Select(gr => new
         {
             TypeId = gr.Key.ItemTypeId ,
             Income =  gr.Key.InvoiceType == InvoiceType.INCOME ? gr.Sum(y => y.Price) : 0,
             Outcome=  gr.Key.InvoiceType == InvoiceType.OUTCOME ? gr.Sum(y => y.Price) : 0,
         })
    .ToList();  

Error:

NHibernate.Util.ADOExceptionReporter Conversion failed when converting the nvarchar value 'INCOME ' to data type int.
System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting the nvarchar value 'INCOME ' to data type int.
   v System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   v System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   v System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   v System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
   v System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
   v System.Data.SqlClient.SqlDataReader.Read()
   v NHibernate.Driver.NHybridDataReader.Read()
   v NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies, IResultTransformer forcedResultTransformer, QueryCacheResultBuilder queryCacheResultBuilder)
   v NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies, IResultTransformer forcedResultTransformer, QueryCacheResultBuilder queryCacheResultBuilder)
   v NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters, IResultTransformer forcedResultTransformer, QueryCacheResultBuilder queryCacheResultBuilder)

NHibernate.Util.ADOExceptionReporter Conversion failed when converting the nvarchar value 'INCOME ' to data type int.
System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting the nvarchar value 'INCOME ' to data type int.
   v NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters, IResultTransformer forcedResultTransformer, QueryCacheResultBuilder queryCacheResultBuilder)
   v NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters)
   v NHibernate.Loader.Hql.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters)
   v NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters)
   v NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results)
   v NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, Object filterConnection)

However it works after I move condition inside Sum:

Session.Query<InvoiceItem>()
    .Where(it=> it.Invoce.Date >= new DateTime(2021,1,1))
    .GroupBy(it => new {ItemTypeId = it.ItemTypeId}) 
    .Select(gr =>
        new
        {
             TypeId = gr.Key.ItemTypeId ,
             Income = gr.Sum(y =>  y.Invoce.InvoiceType == InvoiceType.INCOME ? y.Price : 0),
             Outcome= gr.Sum(y =>  y.Invoce.InvoiceType == InvoiceType.OUTCOME ? y.Price : 0),
         })
    .ToList();

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions