How to cast a value to long before aggregating it?

1.1k views Asked by At

As of EF core 2.1.4, if we cast an int value to long or long? before aggregation (maybe to avoid arithmetic overflow), this cast does not affect the generated query and the overflow happens anyway.

using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;

namespace EfCoreBugs
{
  class Program
  {
    static void Main(string[] args)
    {
      using (var dbContext = new MyDbContext())
      {
        Console.WriteLine(dbContext.Payments.Sum(x => (long?)x.Amount));
      }
      Console.ReadLine();
    }

    public class MyDbContext : DbContext
    {
      protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
      {
        optionsBuilder.UseSqlServer(@"Server=.;Database=EfCoreBugs;Trusted_Connection=True;MultipleActiveResultSets=True;");
      }
      public DbSet<Payment> Payments { get; set; }
    }

    public class Payment
    {
      public int Id { get; set; }
      public int Amount { get; set; }
    }
  }
}

The genrated query is:

SELECT SUM([x].[Amount])
FROM [Payments] AS [x]

is there any way to fix this overflow problem? (Other than changing the datatype of Amount to long)

1

There are 1 answers

4
TheGeneral On BEST ANSWER

Try Convert.ToInt64(x.Amount)

it may translate to

SELECT SUM(CONVERT(bigint, [x].[Amount])) FROM [Payments] AS [x] 

and run without overflow

For future readers. this really depends on the ORM and it may not work in all cases