我有一个查询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;
我一直得到例外:
输入字符串的格式不正确
电气==“”
时会出现主要问题答案 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;
}
}
电气==“”
时会出现主要问题