DB decimal to System.Decimal type conversion overflow

Posts   
 
    
idsn11
User
Posts: 39
Joined: 06-May-2008
# Posted on: 06-May-2008 10:12:53   

Hi!

I've encountered problem with DB decimal (38,25) type.

Environment:

SQL server - MS SQL2005 .Net version - 2.0.50727 LLBLGenPro version - 2.5 Final (released on 2007-09-24)

As I think LLBLGen tries to convert decimal DB type to System.Decimal type automatically. This works good on decimals with small scale. But in my case (scale = 25, value = 22642.0000000002000000000000001) this fails to System.OverflowException (conversion overflow):


   in System.Data.SqlClient.SqlBuffer.get_Decimal()
   in System.Data.SqlClient.SqlBuffer.get_Value()
   in System.Data.SqlClient.SqlDataReader.GetValueInternal(Int32 i)
   in System.Data.SqlClient.SqlDataReader.GetValues(Object[] values)
   in SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.ExecuteMultiRowRetrievalQuery(IRetrievalQuery queryToExecute, ITransaction containingTransaction, IEntityCollection collectionToFill, Boolean allowDuplicates, IEntityFields fieldsUsedForQuery, IFieldPersistenceInfo[] fieldPersistenceInfos)
   in SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.PerformGetMultiAction(ITransaction containingTransaction, IEntityCollection collectionToFill, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, IPrefetchPath prefetchPathToUse, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize)
   in SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.GetMulti(ITransaction containingTransaction, IEntityCollection collectionToFill, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IEntityFactory entityFactoryToUse, IPredicate selectFilter, IRelationCollection relations, IPrefetchPath prefetchPathToUse, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize)
   in SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase`1.GetMulti(IPredicate selectFilter, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IRelationCollection relations, IPrefetchPath prefetchPathToUse, ExcludeIncludeFieldsList excludedIncludedFields, Int32 pageNumber, Int32 pageSize)
   in SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase`1.GetMulti(IPredicate selectFilter)

Revert operation (updating to DB) (with the same value) throws exception too:


   in System.Data.SqlTypes.SqlDecimal.ToDecimal()
   in System.Data.SqlTypes.SqlDecimal.get_Value()
   in System.Data.SqlClient.TdsParser.AdjustDecimalScale(Decimal value, Int32 newScale)
   in System.Data.SqlClient.TdsParser.TdsExecuteRPC(_SqlRPC[] rpcArray, Int32 timeout, Boolean inSchema, SqlNotificationRequest notificationRequest, TdsParserStateObject stateObj)
   in System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
   in System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
   in System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
   in System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   in SD.LLBLGen.Pro.ORMSupportClasses.ActionQuery.Execute()

I found one forum thread (http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=1583&HighLight=1) that partially rorresponds to my situation but the thread discussion is not finished successfully.

As I understand "TypeConverter using" this feature applies after primary db-to-basic-net-type conversion and it's useless in my situation.

Thus 2 questions:

  1. Does LLBLGen allow to use System.Data.SqlTypes.SqlDecimal instead of System.Decimal as conversion target type?
  2. If does not - How I can solve the problem described?

Dmitry

Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 06-May-2008 12:35:36   

LLBLGenPro version - 2.5 Final (released on 2007-09-24)

Although nothing in the changelog that shows a resolution to your problem, I personaly recommend that you use the latest available release. As you are using a very old release.

We will check out this issue and get back to you.

idsn11
User
Posts: 39
Joined: 06-May-2008
# Posted on: 06-May-2008 12:47:13   

Thanks for quik reply!

I'll try latest LLBLGen version and be waiting soon problem resolution.

Now I try to modify db column type (from decimal) to varchar and use System.ComponentModel.DecimalConverter

Dmitry

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39887
Joined: 17-Aug-2003
# Posted on: 06-May-2008 16:51:58   

If there's an overflow in the datareader, we can't do much about it. The code reading the values is db generic, so we can't refer to db specific types there.

We added a 'workaround' to adapter for this, where a developer could intercept the exception and do the proper retrieval. You should override in a partial class of the Dao class of the entity this occurs in the method HandleValueReadErrors. There you will receive the datareader, the exception and the object array into which the values should be placed in. In the override you should read the values for each column in the active datarow in the reader (so the reader has x columns, you should call x times Getvalue(with the index) and place the value in the right slot in the object array).

When done, return true.

This is a low-level workaround, as we can't otherwise fix this. We call GetValues(objectarray) and inside the datareader it apparently causes an overflow as the value can't be placed inside a normal .NET decimal.

You always have to convert it to a normal .net decimal though. So you will get loss of precision.

Frans Bouma | Lead developer LLBLGen Pro
idsn11
User
Posts: 39
Joined: 06-May-2008
# Posted on: 07-May-2008 11:20:33   

Thanks! I'll try this issue

Dmitry