Forum:  Bugs & Issues

Thread:  ArgumentException in Oracle - Value isn't of type 'System.Int16

TomDog (User)   Posted on: 26-Feb-2019 11:10:22.
Finding.Where(f => f.FindingSourceID != 5)
works fine in SQL but in Oracle gives
Value isn't of type 'System.Int16'Parameter name: value

at SD.LLBLGen.Pro.ORMSupportClasses.SystemTypeConverterBase`1.ConvertTo(ITypeDescriptorContext context, CultureInfo culture, Object value, Type destinationType)
at SD.LLBLGen.Pro.ORMSupportClasses.DbSpecificCreatorBase.CreateParameter(IEntityFieldCore field, IFieldPersistenceInfo persistenceInfo, ParameterDirection direction, Object valueToSet)
at SD.LLBLGen.Pro.ORMSupportClasses.FieldCompareValuePredicate.ToQueryText(Boolean inHavingClause)
at SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression.ToQueryText(Boolean inHavingClause)
at SD.LLBLGen.Pro.ORMSupportClasses.PredicateExpression.ToQueryText(Boolean inHavingClause)
at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.AppendWhereClause(IPredicate filter, QueryFragments destination, IQuery query)
at SD.LLBLGen.Pro.DQE.Oracle.DynamicQueryEngine.CreateSelectDQImpl(QueryParameters parameters, DbConnection connectionToUse)
at SD.LLBLGen.Pro.DQE.Oracle.DynamicQueryEngine.CreatePagingSelectDQ(QueryParameters parameters, DbConnection connectionToUse)
at SD.LLBLGen.Pro.ORMSupportClasses.DynamicQueryEngineBase.CreateSelectDQ(QueryParameters parameters, DbConnection connectionToUse)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.CreateSelectDQ(QueryParameters parameters)
at AQD.Model.Oracle.DataAccessAdapter.CreateSelectDQ(QueryParameters parameters)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollectionInternal(QueryParameters parameters)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterCore.FetchEntityCollection(QueryParameters parameters)
at SD.LLBLGen.Pro.ORMSupportClasses.DataAccessAdapterBase.<>c__DisplayClass10_0.<FetchEntityCollection>b__0()
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProvider2.ExecuteEntityProjection(QueryExpression toExecute)
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.ExecuteExpression(Expression handledExpression, Type typeForPostProcessing)
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute(Expression expression)
at SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.System.Collections.IEnumerable.GetEnumerator()
Finding.Where(f => f.FindingSourceID != (short)5)

FindingSourceID is a short?

this.AddElementFieldMapping("FindingEntity", "FindingSourceID", "FINDING_SOURCE_ID", true, "Decimal", 0, 5, 0, false, "", new SD.LLBLGen.Pro.ORMSupportClasses.ChangeTypeConverter<System.Int16>(), typeof(System.Int32), 32);
this.AddElementFieldMapping("FindingEntity", "FindingSourceID", "Finding_Source_ID", true, "SmallInt", 0, 5, 0, false, "", null, typeof(System.Int16), 32);
Otis (LLBLGen Pro Team)   Posted on: 26-Feb-2019 16:02:21.
FindingSourceID is a short?

Heh I first thought "Why are you asking me?" but you meant Nullable<short> Laugh

the problem here is that the value is FROM model TO DB, so it uses the TO convert. This means it converts a value in the type of the model TO the type of the DB. The value therefore has to be a short, otherwise the type converter doesn't work. On SQL Server you're not using the type converter so it works there.

The type converter normally works fine as you convert a short inside the entity to an int32 parameter and when the is read from the DB it is converted to a short.

It looks odd, as normally there's an implicit conversion going on most of the time between ints and shorts but here the type converter does a strict 'is' check of the value with the model type (short) and that fails. So this is 'by design' (I know it's crappy, but it is Regular Smiley. It's not really 'intentional' but a side effect of the untypedness of the predicate system)

TomDog (User)   Posted on: 27-Feb-2019 09:27:14.
But if I put the typeconverter back that I needed pre v5.5 it works.
this.AddElementFieldMapping("FindingEntity", "FindingSourceID", "FINDING_SOURCE_ID", true, "Decimal", 0, 5, 0, false, "", new AQD.Helpers.TypeConverters.SmallIntegerNumericConverter(), typeof(System.Int32), 32);
Otis (LLBLGen Pro Team)   Posted on: 27-Feb-2019 10:01:03.
But that's your own type converter I presume? If so, it doesn't do a test whether the value to use to convert to the destination type is actually of the source type, most likely (as that would fail). The system type converters shipped in the runtime do, hence the problem here.

It might be this check is a bit too strict, after all, one could argue the conversion will fail anyway later on if the value can't be converted to the destination type anyway.

We'll look into whether we can lift this restriction.

Otis (LLBLGen Pro Team)   Posted on: 27-Feb-2019 10:58:22.
The system type converter uses a cast to pass the value on to the actual conversion method. The test with 'is' is to prevent a lame invalidcastexception without more info. However, it's a bit too strict: value conversions aren't taken into account (casting an int to a short is valid after all).

So we'll change the code a bit: we'll do the cast first and if it results in an exception, we'll throw the exception we're doing now. This should both prevent values that are totally invalid (passing a string to this type converter for instance) and give more flexibility.

(edit) Of course this fails because the value is boxed... Dissapointed Will see if there's a workaround around that.

//this works:
int i = 42;
short j = (int)i;

// this fails:
object i = 42;
short j = (int)i;

(edit) can only solve this by checking first if it's a short, if not, use Convert.ChangeType() on the value, which has the side effect that passing in "1" also works: it's happily converted to the destination type. I guess it's a bonus for the one edge case where this pops up (the input of "1" should have been caught earlier by the user code anyway)

Fixed in next build.
Otis (LLBLGen Pro Team)   Posted on: 27-Feb-2019 16:55:08.
Hotfix is now available

TomDog (User)   Posted on: 28-Feb-2019 11:40:30.
Yep sorted - thanksLaugh