Skip to content

version 5.3 failed to cast enum as nvarchar #2446

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Nazgaul opened this issue Jul 22, 2020 · 6 comments
Closed

version 5.3 failed to cast enum as nvarchar #2446

Nazgaul opened this issue Jul 22, 2020 · 6 comments

Comments

@Nazgaul
Copy link

Nazgaul commented Jul 22, 2020

All my enum are mapped as nvarchar and the string value is persist to the database.

All my linq queries now is failing
Conversion failed when converting the nvarchar value 'Flagged' to data type int.

The enum values are
public enum ItemState
{
Ok,
Deleted,
Pending,
Flagged
}
I revert back to 5.2.7 - and hopefully a fix will be soon.

Thanks

The full exception is:

NHibernate.Exceptions.GenericADOException : Failed to execute query batch[SQL: select document0_.Id as col_0_0_, document0_.Name as col_1_0_, document0_.CourseName as col_2_0_, cast(document0_.DocumentType as nvarchar(50)) as col_3_0_, document0_.VoteCount as col_4_0_, document0_.Price as col_5_0_, document0_.CreationTime as col_6_0_, document0_.Views as col_7_0_, document0_.Downloads as col_8_0_, document0_.Purchased as col_9_0_ from sb.[Document] document0_ where document0_.UserId=? and document0_.[State]=?]
---- System.Data.SqlClient.SqlException : Conversion failed when converting the nvarchar value 'Flagged' to data type int.
at NHibernate.Multi.QueryBatch.ExecuteBatchedAsync(CancellationToken cancellationToken)
at NHibernate.Multi.QueryBatch.ExecuteAsync(CancellationToken cancellationToken)
at NHibernate.Multi.QueryBatchExtensions.FutureList1.GetValueAsync(CancellationToken cancellationToken) at NHibernate.Multi.QueryBatchExtensions.FutureEnumerable1.GetEnumerableAsync(CancellationToken cancellationToken)
at

@fairking
Copy link

fairking commented Jul 22, 2020

Version: 5.3.0

I agree. I have the same issues. I am using EnumStringType in all my enum mappings.

EnumStringType<MyEnum>

The actual error:

---> System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting the varchar value 'Completed' to data type int.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
   at System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
   at System.Data.SqlClient.SqlDataReader.<>c__DisplayClass186_0.<ReadAsync>b__1(Task t)
   at System.Data.SqlClient.SqlDataReader.InvokeRetryable[T](Func`2 moreFunc, TaskCompletionSource`1 source, IDisposable objectToDispose)
--- End of stack trace from previous location where exception was thrown ---
   at NHibernate.Driver.NHybridDataReader.ReadAsync(CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Driver\NHybridDataReader.cs:line 133
   at NHibernate.Loader.Loader.DoQueryAsync(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies, IResultTransformer forcedResultTransformer, QueryCacheResultBuilder queryCacheResultBuilder, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Loader\Loader.cs:line 295
   at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollectionsAsync(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies, IResultTransformer forcedResultTransformer, QueryCacheResultBuilder queryCacheResultBuilder, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Loader\Loader.cs:line 80
   at NHibernate.Loader.Loader.DoListAsync(ISessionImplementor session, QueryParameters queryParameters, IResultTransformer forcedResultTransformer, QueryCacheResultBuilder queryCacheResultBuilder, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Loader\Loader.cs:line 1461
ClientConnectionId:dd348057-1bae-4c46-b2b2-09261c03234d
Error Number:245,State:1,Class:16
   --- End of inner exception stack trace ---
   at NHibernate.Loader.Loader.DoListAsync(ISessionImplementor session, QueryParameters queryParameters, IResultTransformer forcedResultTransformer, QueryCacheResultBuilder queryCacheResultBuilder, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Loader\Loader.cs:line 1471
   at NHibernate.Loader.Loader.ListIgnoreQueryCacheAsync(ISessionImplementor session, QueryParameters queryParameters, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Loader\Loader.cs:line 1345
   at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.ListAsync(ISessionImplementor session, QueryParameters queryParameters, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Hql\Ast\ANTLR\QueryTranslatorImpl.cs:line 65
   at NHibernate.Engine.Query.HQLQueryPlan.PerformListAsync(QueryParameters queryParameters, ISessionImplementor session, IList results, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Engine\Query\HQLQueryPlan.cs:line 65
   at NHibernate.Impl.SessionImpl.ListAsync(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, Object filterConnection, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Impl\SessionImpl.cs:line 269
   at NHibernate.Impl.SessionImpl.ListAsync(IQueryExpression queryExpression, QueryParameters queryParameters, IList results, Object filterConnection, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Impl\SessionImpl.cs:line 285
   at NHibernate.Impl.AbstractSessionImpl.ListAsync(IQueryExpression queryExpression, QueryParameters parameters, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Impl\AbstractSessionImpl.cs:line 57
   at NHibernate.Impl.AbstractQueryImpl2.ListAsync(CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Impl\AbstractQueryImpl2.cs:line 81
   at NHibernate.Linq.DefaultQueryProvider.ExecuteQueryAsync(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Async\Linq\DefaultQueryProvider.cs:line 58
   at NHibernate.Linq.DefaultQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken) in C:\Code\nhibernate-core\src\NHibernate\Linq\DefaultQueryProvider.cs:line 182

((NHibernate.Linq.NhLinqExpression)queryExpression).Key:

.Count[MyApp.Core.Entities.ChecklistItem, MyApp.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null](.Fetch[MyApp.Core.Entities.ChecklistItem, MyApp.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null,MyApp.Core.Entities.Checklist, MyApp.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null](NHibernate.Linq.NhQueryable`1[MyApp.Core.Entities.ChecklistItem], Quote((x, ) => (x.Checklist)), ), Quote((x, ) => (AndAlso(AndAlso(AndAlso(AndAlso(String.op_Equality(x.Checklist.Workflow.Id, p1<System.String>), OrElse(Equal(x.Checklist.WorkflowState, NULL), Equal(Convert(x.Checklist.WorkflowState), Convert(p3<MyApp.Core.Entities.WorkflowStateEnum>)))), Equal(x.Checklist.IsDeleted, p4<System.Boolean>)), Equal(x.IsDeleted, p5<System.Boolean>)), OrElse(Equal(Convert(x.ChecklistState), p6<System.Int32>), Equal(Convert(x.ChecklistState), p7<System.Int32>))))), )

(((NHibernate.Linq.NhLinqExpression)queryExpression)._expression).DebugView:

.Call System.Linq.Queryable.Count(
    .Call NHibernate.Linq.EagerFetchingExtensionMethods.Fetch(
        .Constant<NHibernate.Linq.NhQueryable`1[MyApp.Core.Entities.ChecklistItem]>(NHibernate.Linq.NhQueryable`1[MyApp.Core.Entities.ChecklistItem]),
        '(.Lambda #Lambda1<System.Func`2[MyApp.Core.Entities.ChecklistItem,MyApp.Core.Entities.Checklist]>)),
    '(.Lambda #Lambda2<System.Func`2[MyApp.Core.Entities.ChecklistItem,System.Boolean]>))

.Lambda #Lambda1<System.Func`2[MyApp.Core.Entities.ChecklistItem,MyApp.Core.Entities.Checklist]>(MyApp.Core.Entities.ChecklistItem $x)
{
    $x.Checklist
}
.Lambda #Lambda2<System.Func`2[MyApp.Core.Entities.ChecklistItem,System.Boolean]>(MyApp.Core.Entities.ChecklistItem $x)
{
    (($x.Checklist).Workflow).Id == "bl4l5gf04p66zse2" && (($x.Checklist).WorkflowState == null || (System.Nullable`1[System.Int32])($x.Checklist).WorkflowState ==
    (System.Nullable`1[System.Int32]).Constant<MyApp.Core.Entities.WorkflowStateEnum>(Draft)) && ($x.Checklist).IsDeleted ==
    False && $x.IsDeleted == False && ((System.Int32)$x.ChecklistState == 0 || (System.Int32)$x.ChecklistState == 1)
}

WorkflowState is a type of WorkflowStateEnum?
ChecklistState is a type of ChecklistStateEnum

The actual query:

result.CheckItemsPending = await Db.Query<ChecklistItem>().Fetch(x => x.Checklist)
     .CountAsync(x => 
        x.Checklist.Workflow.Id == workflow.Id 
        && (x.Checklist.WorkflowState == null || x.Checklist.WorkflowState == workflow.WorkflowState) 
        && x.Checklist.IsDeleted == false && x.IsDeleted == false 
        && (x.ChecklistState == ChecklistStateEnum.Awaiting || x.ChecklistState == ChecklistStateEnum.Progress)
    );

@maca88
Copy link
Contributor

maca88 commented Jul 22, 2020

@Nazgaul can you share how your linq query looks like and what enum type (e.g. EnumStringType) are you using for mapping the State property?
From the exception it seems like to be: session.Query<Document>().Where(o => o.UserId == userId && o.State == ItemState.Flagged).ToFuture().ToList(), but I couldn't reproduce the issue with such query.

@fairking your issue is already fixed by #2443.

@Nazgaul
Copy link
Author

Nazgaul commented Jul 22, 2020

@maca88

this is my linq query
var documentCoursesFuture = _session.Query()
.Fetch(f => f.User)
.Where(w => w.User.Id == query.Id && w.Status.State == ItemState.Ok)
.Select(s => s.Course.Id).Distinct()
.ToFuture();

NHibernate.Exceptions.GenericADOException : Failed to execute query batch[SQL: select distinct document0_.CourseName as col_0_0_ from sb.[Document] document0_ where document0_.UserId=? and document0_.[State]=?]
---- System.Data.SqlClient.SqlException : Conversion failed when converting the nvarchar value 'Flagged' to data type int.

the mapping is
Map(x => x.State)
.CustomType<GenericEnumStringType>().Not.Nullable();

the EnumStringType inherit from EnumStringType support ignore case

public override object? GetInstance(object code)
{
if (!(code is string p))
{
return null;
}
return Enum.Parse(typeof(TEnum), p, true);
}

@Nazgaul
Copy link
Author

Nazgaul commented Jul 22, 2020

@maca88
the fetch is causing this issue. remove the line Fetch(f => f.User) will make my unit test to pass.

@maca88
Copy link
Contributor

maca88 commented Jul 22, 2020

@Nazgaul thanks for the info, closing the issue as it was already reported in #2439 and fixed.

@fairking
Copy link

fairking commented Jul 22, 2020

Thank you guys. Tested the branch origin/5.3.x enums and everything else is working with no issues so far now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants