4

我有一个查询 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

4 回答 4

5

不幸的是,该框架没有提供一种很好的干净方式来处理失败的解析场景。在提供的内容中,它们仅抛出异常或使用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();
}

ps,你使用的Convert.ToInt32()方法不对。它与调用相同Int32.Parse()并且返回可空值,它将抛出失败。

于 2013-06-05T21:39:59.350 回答
4

我会检查列中的数据是否不包含前导/尾随空格 - 即"15 ",而不是"15"在尝试转换之前是否(或可能)修剪它:

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

顺便说一句:与错误无关,但我会使用let语句来引入局部变量并进行一次转换:

let x = Int32.Parse(row.Field<String>("electrical").Trim()) 
where x >= 100...
于 2013-05-29T19:20:17.683 回答
0

我什么也做不了,所以我重新做了整个方法:

    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;
        }
    }

主要问题发生在电气==“”时

于 2013-06-03T17:19:14.067 回答
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;
于 2013-06-03T17:35:44.587 回答