Dennis
Dennis

Reputation: 23

What is the corresponding data type in C# for a packed decimal in iSeries?

Trying write a simple API to access a Db2 database table with packed decimal fields. Without converting the value, is there a corresponding data type in C#? I keep getting a mismatching data type error.

{"Specified cast is not valid."} Data: {System.Collections.ListDictionaryInternal} HResult: -2147467262 HelpLink: null InnerException: null Message: "Specified cast is not valid." Source: "IBM.Data.DB2.Core" StackTrace: " at IBM.Data.DB2.Core.DB2DataWrapper.get_Int32Value()\r\n at IBM.Data.DB2.Core.DB2DataReader.GetInt32(Int32 i)\r\n at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable1.AsyncEnumerator.<MoveNextAsync>d__17.MoveNext()\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.ValueTaskAwaiter1.GetResult()\r\n at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.d__221.MoveNext()\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.<SingleOrDefaultAsync>d__221.MoveNext()\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAw aiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()\r\n at CoreCodeCamp.Data.TestRepository.<GetAccountAsync>d__6.MoveNext() in TestRepository.cs:line 60\r\n at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter1.GetResult()\r\n at CoreCodeCamp.Controllers.TestController.d__4.MoveNext() in TestController.cs:line 38" TargetSite: {Int32 get_Int32Value()}

Here is the code...

DB2 Camps table:

Field      Type  Length     
CAMPID     P     5,0    
NAME       A     50
MONIKER    A     20     
EVENTDATE  Z     26
LENGTH     S     3,0
LOCATIONID P     5,0

CampsController.cs:

[HttpGet]
public async Task<ActionResult<CampModel[]>> Get(bool includeTalks = false)
{
  try
  {
    var results = await _repository.GetAllCampsAsync(includeTalks);

    return _mapper.Map<CampModel[]>(results);
  }
  catch (Exception)
  {
    return this.StatusCode(StatusCodes.Status500InternalServerError, "Database Failure");
  }
}

DBcontext.cs:

using IBM.EntityFrameworkCore;
using IBM.EntityFrameworkCore.Storage.Internal;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseDb2(_config.GetConnectionString("CodeCamp"),
    p =>
    {
        p.SetServerInfo(IBMDBServerType.AS400, IBMDBServerVersion.AS400_07_01);
        p.UseRowNumberForPaging();
        p.MaxBatchSize(1);
    });

}

Camp.cs Entity:

namespace CoreCodeCamp.Data
{
    public class Camp
    {
        public int CampId { get; set; }
        public string Name { get; set; }
        public string Moniker { get; set; }
        public Location Location { get; set; }
        public DateTime EventDate { get; set; } = DateTime.MinValue;
        public int Length { get; set; } = 1;
        public ICollection<Talk> Talks { get; set; }
    }
}

Repository.cs:

public async Task<Camp[]> GetAllCampsAsync(bool includeTalks = false)
{
  _logger.LogInformation($"Getting all Camps");

  IQueryable<Camp> query = _context.Camps;

  return await query.ToArrayAsync();
}

Upvotes: 0

Views: 440

Answers (1)

Charles
Charles

Reputation: 23793

You should show your code...

But the IBM i .NET data provider should have a iDB2Decimal structure used for packed numeric.

iDB2Decimal.Value returns a C# Decimal type.

EDIT
ok, so you have both packed decimal CAMPID P 5,0
and zoned decimal LENGTH S 3,0

which should correspond to iDB2Decimal and iDB2Numeric.

Both of which have a Value property that returns a C# Decimal.

So I'd recommend changing your model from int to Decimal to those two fields.
Location is also packed in the DB, I'm not sure what you've done with your Location type... LOCATIONID P 5,0
public Location Location { get; set; }

Upvotes: 2

Related Questions