在LINQ中将字符串转换为Int

时间:2013-05-29 18:01:11

标签: c# .net string linq casting

我有一个查询DataTable的LINQ查询。在DataTable中,字段是一个字符串,我需要将它与一个整数进行比较,基本上是:

if ((electrical >= 100 && electrical <= 135) || electrical == 19)
{
    // The device passes
}

问题是,我试图在LINQ中这样做:

        var eGoodCountQuery = 
            from row in singulationOne.Table.AsEnumerable()
            where (Int32.Parse(row.Field<String>("electrical")) >= 100 &&
                   Int32.Parse(row.Field<String>("electrical")) <= 135) &&
                   Int32.Parse(row.Field<String>("electrical")) != 19 &&
                   row.Field<String>("print") == printName
            select row;

我一直得到例外:

  

输入字符串的格式不正确

电气==“”

时会出现主要问题

4 个答案:

答案 0 :(得分:4)

我会检查列中的数据是否不包含前导/尾随空格 - 即"15 "而不是"15",如果它确实(或可能会)修改它,然后再尝试转换:< / p>

Int32.Parse(row.Field<String>("electrical").Trim())

BTW:与错误无关但我使用let语句引入局部变量并进行一次转换:

let x = Int32.Parse(row.Field<String>("electrical").Trim()) 
where x >= 100...

答案 1 :(得分:4)

不幸的是,该框架没有提供一种很好的干净方法来处理失败的解析方案。在提供的内容中,它们只抛出异常或使用out参数,这两个参数都不能与linq查询一起使用。如果您正在解析的任何一个值失败,整个查询将失败,您实际上无法使用out参数。您需要提供一种方法来处理解析,而不会抛出,也不需要使用out参数。

您可以通过多种方式处理此问题。在失败的情况下实现它,您将返回一些默认的标记值。

public static int ParseInt32(string str, int defaultValue = 0)
{
    int result;
    return Int32.TryParse(str, out result) ? result : defaultValue;
}

或者我建议的是,返回一个可以为空的值(null表示它失败了。)

public static int? ParseInt32(string str)
{
    int result;
    return Int32.TryParse(str, out result) ? result : null;
}

这样可以大大简化您的查询,同时仍然保持可读性。

public bool GetElectricalStatus(string printName)
{
    var query =
        from row in singulationOne.Table.AsEnumerable()
        where row.Field<string>("print") == printName
        // using the nullable implementation
        let electrical = ParseInt32(row.Field<string>("electrical"))
        where electrical != null
        where electrical == 19 || electrical >= 100 && electrical <= 135
        select row;
    return !query.Any();
}

p.s。,您对Convert.ToInt32()方法的使用不正确。它与调用Int32.Parse()返回可为空的内容相同,它会失败。

答案 2 :(得分:0)

为什么不创建一个执行评估的函数,并在Linq查询中调用它。将逻辑放入以检查其中包含的数据的有效性(因此,如果您无法解析数据,则应返回 false )...

功能:

bool IsInRange(string text, int lower, int upper, params int[] diqualifiers)
{
  int value = int.MinValue;
  if (!int.TryParse(text, out value)) {
    return false;
  }
  if (!(value >= lower && value <= upper)) {
    return false;
  }
  if (disqualifiers != null && disqualifiers.Any(d => d == value)) {
    return false;
  }
  return true;
}

Linq查询...

var eGoodCountQuery = 
            from row in singulationOne.Table.AsEnumerable()
            where 
              IsInRange(row.Field<String>("electrical"), 100, 135, 19) 
              && row.Field<String>("print") == printName
            select row;

答案 3 :(得分:-1)

我无法工作,所以我重新做了整个方法:

    public bool GetElectricalStatus(string printName)
    {
        List<object> eGoodList = new List<object>();
        var eGoodCountQuery =
            from row in singulationOne.Table.AsEnumerable()
            where row.Field<String>("print") == printName
            select row.Field<String>("electrical");

        foreach (var eCode in eGoodCountQuery)
        {
            if (!string.IsNullOrEmpty(eCode.ToString()))
            {
                int? eCodeInt = Convert.ToInt32(eCode);
                if (eCodeInt != null &&
                    (eCodeInt >= 100 && eCodeInt <= 135) || eCodeInt == 19)
                {
                    eGoodList.Add(eCode);
                }
            }
        }
        if (eGoodList.Count() > 0)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

电气==“”

时会出现主要问题