0

I have the following method (below), which throws this error: "Arithmetic operation resulted in an overflow". The table contains 192526 rows and 9 columns.

Is there a way to place a breakpoint for each item inside the "dt.Rows.Add()"? I.e. can I define which Row and which Column this is failing on, etc?

I could do a "StepInto" once I reach this line. And I saw this error "error CS0103: The name 'dt' does not exist in the current context" (I assume that is not the one that is causing the eventual failure), in the line "dt.AsEnumerable().Sum(dr => dr.Field("Balance"))," But - there are way too many entries to do "StepOver" for each, and before it gets into next one.

  public DataTable AddTrailer(DataTable dt)
    {
        try
        {
            if (dt.TableName.Equals("Summary"))
            {
                Console.WriteLine("Summary Table");

                dt.Rows.Add(
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    dt.AsEnumerable().Sum(dr => dr.Field<int>("Balance")),
                    dt.AsEnumerable().Sum(dr => dr.Field<int>("Total1")),
                    dt.AsEnumerable().Sum(dr => dr.Field<int>("Total2"))
                );
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception thrown in the AddTrailer - Summary");
            throw;
        }

        return dt;
    }

If I use the suggestion as "dt.AsEnumerable().Sum(dr => (long)dr.Field("Balance"))" - I will get another error: "{"Value was either too large or too small for an Int32.Couldn't store <21488943305> in Balance|Current Balance Column. Expected type is Int32."}"

I cannot even figure out why it is complaining as the number of rows (or rows * columns) should not be that high (to be outside of the regular int).

KVN
  • 863
  • 1
  • 17
  • 35
  • Try `dt.AsEnumerable().Sum(dr => (long)dr.Field("Balance")),` also `throw ex;` is a bad idea as it will wipe the stack trace, use `throw;` instead – Charlieface Jul 07 '22 at 20:43
  • @Charlieface Thanks. When I use your suggestion now I'm getting a new one: "{"Value was either too large or too small for an Int32.Couldn't store <21488943305> in Balance|Current Balance Column. Expected type is Int32."}" – KVN Jul 07 '22 at 21:09
  • Guess you need to change the `DataTable` definition to use `long`. You can't fit such a big number in `int` there is no way around it. – Charlieface Jul 07 '22 at 23:09

1 Answers1

0

Actually, it seems that the SUM was indeed over the Max for the Int32. To get around the problem - I copied those columns into new ones but of the Int64 type instead (and then removed the original Int32 columns). And then it was working fine.

    private Int64 CopyColumnAndGetSum(DataTable dt, string currentColumnName, string newColumnName)
    {
        Int64 sum = 0;
        DataColumn colBal64 = new DataColumn();
        colBal64.ColumnName = newColumnName;
        colBal64.DataType = typeof(Int64);
        dt.Columns.Add(colBal64);

        for (int i = 0; i <= dt.Rows.Count - 1; i++)
        {
            DataRow dr = dt.Rows[i];
            dr[newColumnName] = dr[currentColumnName];
        }
        sum = dt.AsEnumerable().Sum(dr => dr?.Field<Int64?>(newColumnName) ?? 0);
        return sum;
    }
KVN
  • 863
  • 1
  • 17
  • 35