【问题标题】:Get Maximum value code from a datatable in c# throws InvalidCastException从 C# 中的数据表中获取最大值代码抛出 InvalidCastException
【发布时间】:2011-10-15 10:30:12
【问题描述】:

我有一个类似于

的数据表
Rank  Year  Value
1     1990  1234556.5676
2     2000  12313.1212 
3     2010  131242.1234

我在以下线程的帮助下编写了以下代码:How to select min and max values of a column in a datatable?

double dMaxValue = 0;
foreach (DataRow dr in dsView.Tables[0].Rows)
{
    double dValue = dr.Field<double>("Value");
    dMaxValue = Math.Max(dMaxValue, dValue);
}

这会引发错误“指定的强制转换无效”。我在这里缺少什么,以及如何在找到 MAX 值后获得年份列的值?年份需要返回给调用程序。

编辑-(解决方案):在 Slacks 的帮助下,我想出了如何完成任务。首先,我发现我的数据表中的数据是字符串类型的,所以将值转换为 double 并确定最大值。然后用一个变量来查找对应的年份。

string sYear = string.Empty;
double dMaxValue = double.MinValue;
foreach (DataRow dr in dsView.Tables[0].Rows)
{
    double dValue = Convert.ToDouble(dr.Field<string>("Value"));
    if (dValue > dMaxValue)
    {
        sYear = dr["Year"].ToString();
    }
    dMaxValue = Math.Max(dMaxValue, dValue);                            
}
return sYear;

【问题讨论】:

    标签: c#


    【解决方案1】:

    您的Value 列可能是decimal,或者可能是float

    You cannot cast directly from a boxed float to a double,所以你需要一个额外的演员表。

    最好使用数据集中字段的实际类型,或者将该类型更改为Double

    【讨论】:

    • 我通过将代码更改为 float dValue = dr.Field&lt;float&gt;("Value");decimal dValue = dr.Field&lt;decimal&gt;("Value"); 尝试了所有数据类型,但没有运气。这是正确的检查方法吗?由于我无权访问数据集..所以我真的无法编辑它。如何从数据集中找到列的类型?
    • @user:dr["Value"].GetType(),或table.Columns["Value"].DataType
    • 感谢您最初的建议。我想了想,发现数据集的所有列数据都是字符串。我已经使用以下方法解决了它:double dValue = Convert.ToDouble(dr.Field&lt;string&gt;("Value"));。但是现在我怎样才能找到对应的年份呢?有没有简单的解决方案?
    • 你需要为年份单独做一个变量,并赋值if的值更大。
    【解决方案2】:

    你是怎么得到年份的?

    您可以对数据视图进行排序:

               http://msdn.microsoft.com/en-us/library/system.data.dataview.sort.aspx
    

    然后从排序视图中提取年份。

    【讨论】:

      【解决方案3】:

      尝试这样的事情(使用 System.Linq 和 Extensions,注意用于转换的 let 变量):

      double maxVal = 0; // supposing all your values are > 0
      var maxRow = (from row in dsView.Tables[0].AsEnumerable() 
         let Val = Convert.ToDouble(row.Field<string>("Value"))
         where Val > maxVal
         select new {maxVal = Val, Year = row.Field<int>("Year")}).Last();
      
      return maxRow.Year;
      

      【讨论】:

      • 很遗憾,Max 不能这样做。
      • @cudahead,数据集中的数据是字符串类型的。所以我将您的代码调整为var maxRow = (from row in dsView.Tables[0].AsEnumerable() select new { Val = Convert.ToDouble(row.Field&lt;string&gt;("Value")), Year = Convert.ToDouble(row.Field&lt;string&gt;("Year")) }).Max(x =&gt; x.Val);。首先,这段代码不起作用,我在 maxRow 中没有得到年份。我错过了什么吗?
      • 我想到了一个带有 let 变量的解决方案。请在上面找到我更新的帖子!
      • cudahead,我仍然没有在 maxRow 中看到 Year 或 Val。我确定我错过了一些东西..
      • 好的,现在它应该可以工作了(再次更新)。请注意,这里没有使用 Max()。请检查!
      猜你喜欢
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多