【问题标题】:DataTable type arguments cannot be inferred无法推断 DataTable 类型参数
【发布时间】:2017-11-08 14:55:53
【问题描述】:

在下面的代码中,我为参数数据表中的每一行添加了一个 parameterValue。

但是,我收到以下错误:

“无法从用法中推断方法 'EnumerableRowCollectionExtensions.Select(EnumerableRowCollection, Func)' 的类型参数。请尝试显式指定类型参数。”

谁能帮我理解我需要在代码中明确定义什么类型参数?

下面是错误代码:

parameters.AsEnumerable().Select(x => 
{
    ParameterValue parameterValue = new ParameterValue();
    parameterValue.Name = x["name"].ToString();
    parameterValue.Value = x["value"].ToString();
    parameterList.Add(parameterValue);
 });

这在 foreach 循环中运行良好。这是代码:

foreach (DataRow row in parameters.Rows)
{
   ParameterValue parameterValue = new ParameterValue();
   parameterValue.Name = row["name"].ToString();
   parameterValue.Value = row["value"].ToString();

   parameterList.Add(parameterValue);
}

【问题讨论】:

标签: c# lambda datatable


【解决方案1】:

正确的语法

parameters.AsEnumerable().Select(x => 
{
    ParameterValue parameterValue = new ParameterValue();
    parameterValue.Name = x["name"].ToString();
    parameterValue.Value = x["value"].ToString();
    parameterList.Add(parameterValue);
 });

parameterList.AddRange(parameters.AsEnumerable().Select(x =>            
    new ParameterValue()
    {
        Name = x["name"].ToString(),
        Value = x["value"].ToString()
    }));

旁注: 而不是x["name"].ToString(),您应该通过其类型x.Field<string>("name")访问该字段

【讨论】:

  • 取决于parameterList 是什么,也许它没有AddRange 方法。我会将查询存储在一个变量中,然后使用foreach 一个接一个地添加它们,或者在支持的情况下使用AddRange(allParameterValues)
  • @TimSchmelter:我很抱歉。参数列表为:List parameterList = new List();
  • @fubo 使用 Field 是一种更好的做法,因为类型安全?
  • @rds80 你不需要像Convert.ToInt32(x["foo"]) 这样的任何类型的转换,这是最佳实践stackoverflow.com/a/7104767/1315444
【解决方案2】:

Enumerable.Select 是一种投影 方法。它将TSource 类型的每个输入项投影到TResult 类型的新形式中。因此,它接受一个执行此 TSource > TResult 投影的 selector 委托。您的选择器委托如下所示:

x => 
{
    ParameterValue parameterValue = new ParameterValue();
    parameterValue.Name = x["name"].ToString();
    parameterValue.Value = x["value"].ToString();
    parameterList.Add(parameterValue);
}

即它将DataRow 作为 TSource 并将其投影到.. 什么都没有。您不会从此委托返回任何值。因此编译器无法理解它应该使用哪个TResult

现在解决方案。实际上,你想在这里做两个动作:

  • 将每一行投影到ParameterValue
  • 将每个预计值添加到列表中(新的或现有的)

第一部分是投影。只需使用将 DataRow 作为 TSource 并将 ParameterValue 作为 TResult 返回的委托:

x => new ParameterValue{ Name = x.Field<string>("name"), Value = x.Field<string>("value") }

第二部分可以通过两种方式完成。您可以从所有参数值创建一个新列表。这是一种声明式的编程风格 - 无需指定如何将值添加到列表中,您只需说“我想要列表”:

var parameterList = parameters.AsEnumerable()
      .Select(r => new ParameterValue { 
          Name = r.Field<string>("name"), // note this LINQ to DataSet syntax
          Value = r.Field<string>("value")
      }).ToList();

或者您可以使用简单的 foreach 循环将每个投影值一一添加到现有列表中。但在这里我会使用查询语法进行投影:

var parameterValues = from r in parameters.AsEnumerable()
                      select new ParameterValue { 
                          Name = r.Field<string>("name"),
                          Value = r.Field<string>("value")
                      };

foreach(var parameterValue in parameterValues)
    parameterList.Add(parameterValue);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 2014-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多