Search code examples
c#linqsql-to-linq-conversion

Linq Input string was not in a correct format in MVC


The original SQL Command coded by the old programmers looks like this

SELECT ooe_general_id, SUM(CAST(CAST(amount AS money) AS float)) AS totalAppro, MAX(date) AS lastDate 
FROM  dbo.pmTA_OoeGeneralAppropriation

Datatype: String

Database Values
----------------
3,200,000.00
2916410
28,710,000.00
0.80000000000291
-1000000

When I try to convert the above code to Linq, an error 'Input string was not in a correct format' shows in this line

totalAppro = g.Sum(p => Convert.ToDouble(p.amount))

I tried doing changing the code to

Convert.Double(string, IFormatprovider)  
Convert.ToDouble(String.Format("{0:c}", p.amount)) 
Convert.ToDecimal(p.amount.Replace(",",""))

from these Currency, Convert, SUM LINQ forums but the error still persists.

The question is what am I doing wrong here? Why did my first two codes work but this doesn't? And lastly, why is there an 'Input string was not in a correct format' error?

Thanks in advance.

UPDATE

var totalAppropriationGeneralFund = (from p in db.iBudget_OoeGeneralAppropriation   
                                 where !p.amount.StartsWith("-")
                                 group p by p.ooe_general_id into g    
                                 select g).AsEnumerable().Select(g => new {
                                 id = g.Key,
                                 totalAppro = g.Sum(p => Convert.ToDecimal(p.amount.Replace(",",""))),
                                 date = g.Max(p => p.date)
                             }).ToList();

Solution

  • Firstly

    Don't store or convert datatypes to string and back again. leave them as what they are, convert them for display purposes only, and definitely don't store numeric types as string in a db (just a tip).

    Secondly

    If your slightly worried about accuracy, don't use floating point values like double or float. They are notorious for losing precision and adding artefacts, use a decimal

    Thirdly

    NumberStyles Enumeration : Determines the styles permitted in numeric string arguments that are passed to the Parse and TryParse methods of the integral and floating-point numeric types.

    The above was your problem

    Working example

    var list = new List<string>
       {
          "3,200,000.00",
          "2916410",
          "28,710,000.00",
          "0.80000000000291",
          "-1000000"
       };
    
    var sum = list.Sum(x => decimal.Parse(x, NumberStyles.Any, CultureInfo.InvariantCulture));
    

    Output

    33826410.80000000000291
    

    Full Demo here

    Further reading

    decimal (C# Reference)

    Update

    As noted in the comments by Bagus Tesa, you cant use parse methods in EF or Linq to sql, this has to be done in memory, i would consider changing you under laying datatype and or query