Pregunta

In my C# app I am reading numeric data from my MySQL table. After that, I am searching for a minimal euclidean distance (between table row and an average tuple).

I am reading values from MySQL table into double variables (f1 to f8 and one int variable). I am getting this error on the first line, where I am putting the reader's result into f1. However, when I do random computation after reading my values for example (f1+f8), it returns right/exact result. So why does C# have a problem with the input string?

Here is my code:

for (int k = 1; k <= pocet; k++)
{
    string queryCompare = " SELECT F1 AS Fe1, F2 AS Fe2, F3 AS Fe3, F4 AS Fe4, F5 AS Fe5, F6 AS Fe6, F7 AS Fe7, F8 AS Fe8, cluster FROM features WHERE ID=" + k;
    MySqlCommand cmdCompare = new MySqlCommand(queryCompare, conect);
    readerCompare = cmdCompare.ExecuteReader();
    readerCompare.Read();
    //  MessageBox.Show("OK");
    double f1 = Convert.ToDouble(readerCompare["Fe1"].ToString());  // EXCEPTION HERE
    double f2 = Convert.ToDouble(readerCompare["Fe2"].ToString());
    double f3 = Convert.ToDouble(readerCompare["Fe3"].ToString());
    double f4 = Convert.ToDouble(readerCompare["Fe4"].ToString());
    double f5 = Convert.ToDouble(readerCompare["Fe5"].ToString());
    double f6 = Convert.ToDouble(readerCompare["Fe6"].ToString());
    double f7 = Convert.ToDouble(readerCompare["Fe7"].ToString());
    string f88 = readerCompare["Fe8"].ToString();
    double f8 = Convert.ToDouble(f88, CultureInfo.InvariantCulture);
    int cluster = Convert.ToInt32(readerCompare["cluster"].ToString());

    readerCompare.Close();
    //  MessageBox.Show((f1+f8).ToString());

    switch (cluster)
    {
        case 1:
            euklDist = (double)Math.Sqrt(
                                        Math.Pow(touple[0, 0] - f1, 2) + 
                                        Math.Pow(touple[0, 1] - f2, 2) + 
                                        Math.Pow(touple[0, 2] - f3, 2) + 
                                        Math.Pow(touple[0, 3] - f4, 2) + 
                                        Math.Pow(touple[0, 4] - f5, 2) + 
                                        Math.Pow(touple[0, 5] - f6, 2) + 
                                        Math.Pow(touple[0, 6] - f7, 2) + 
                                        Math.Pow(touple[0, 7] - f8, 2));

            if (euklDist < minCl1)
            {
                minCl1 = euklDist;
                idCl1 = k;
            }
            break;

        case 2:
            euklDist = (double)Math.Sqrt(
                                        Math.Pow(touple[1, 0] - f1, 2) +
                                        Math.Pow(touple[1, 1] - f2, 2) +
                                        Math.Pow(touple[1, 2] - f3, 2) + 
                                        Math.Pow(touple[1, 3] - f4, 2) + 
                                        Math.Pow(touple[1, 4] - f5, 2) +
                                        Math.Pow(touple[1, 5] - f6, 2) +
                                        Math.Pow(touple[1, 6] - f7, 2) +
                                        Math.Pow(touple[1, 7] - f8, 2));

            if (euklDist < minCl2)
            {
                minCl2 = euklDist;
                idCl2 = k;
            }
            break;

        case 3:
            euklDist = (double)Math.Sqrt(
                                        Math.Pow(touple[2, 0] - f1, 2) +
                                        Math.Pow(touple[2, 1] - f2, 2) + 
                                        Math.Pow(touple[2, 2] - f3, 2) +
                                        Math.Pow(touple[2, 3] - f4, 2) +
                                        Math.Pow(touple[2, 4] - f5, 2) + 
                                        Math.Pow(touple[2, 5] - f6, 2) + 
                                        Math.Pow(touple[2, 6] - f7, 2) + 
                                        Math.Pow(touple[2, 7] - f8, 2));

            if (euklDist < minCl3)
            {
                minCl3 = euklDist;
                idCl3 = k;
            }
            break;
    }
}

Records in my db are in this format:

  • from f1 to f7: xx,xxx
  • f8: xx.xxx

I know that f8 has decimal point instead of comma that is why I am using CultureInfo.InvariantCulture for f8.

¿Fue útil?

Solución

You don't need to update the null values, just do this:

Convert.ToDouble(readerCompare["Fe1"]);

The null will be handled by ToDouble and convert it to its default value; 0.

See, here is the ToDouble implementation you'd be using with the above code:

public static double ToDouble(object value)
{
  if (value != null)
    return ((IConvertible) value).ToDouble((IFormatProvider) null);
  else
    return 0.0;
}

UPDATE: alright if you also need to support empty strings then you'll have to change this code a little. First let's build an extension method. Create a new class in your solution and name it SystemExtensions, then paste in this code:

namespace System
{
    public static class SystemExtensions
    {
        public static string ToConvertibleDouble(this object input)
        {
            var s = input as string;
            if (string.IsNullOrEmpty(s.Trim())) { return null; }

            // this will also take care of the separator
            return s.Replace(".", ",");
        }
    }
}

and now let's use it:

Convert.ToDouble(readerCompare["Fe1"].ToConvertibleDouble());
Convert.ToDouble(readerCompare["Fe2"].ToConvertibleDouble());
...
Convert.ToDouble(readerCompare["Fe8"].ToConvertibleDouble());
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top