2013-05-03 47 views
1

我正在尝试编写一些逻辑来确定集合中某个对象的某个属性的所有值是否都是数字并且大于零。我可以很容易地使用ForEach编写这个,但是我想用Linq来做它。我试过这个:Linq to Objects - 为任何非数字数据查询对象

var result = entity.Reports.Any(
    x => 
    x.QuestionBlock == _question.QuestionBlock 
    && (!string.IsNullOrEmpty(x.Data)) && Int32.TryParse(x.Data, out tempVal) 
    && Int32.Parse(x.Data) > 0); 

它不能正常工作。我也试过,希望Int32上的TryParse()在第一次遇到不能被解析为int的字符串时将返回false。但它看起来出来的参数将包含可以解析为一个int的第一个值字符串值。

var result = entity.GranteeReportDataModels.Any(
    x => 
    x.QuestionBlock == _question.QuestionBlock 
    && (!string.IsNullOrEmpty(x.Data)) && Int32.TryParse(x.Data, out tempVal)); 

任何帮助,非常感谢!

+0

如果'TryParse'返回false,'out'参数的值是未定义的。 – Jodrell 2013-05-03 14:58:00

+0

如果'TryParse'返回'false',我相信out参数是0('int'的默认值),但这没有记录。实际上MSDN认为它返回“未初始化”,但这是不可能的,因为根据定义“out”意味着必须在函数返回之前设置一个值。反编译该方法显示,在实际完成任何工作之前,它实际上被设置为0。 – 2013-05-03 15:02:10

+0

@BrianBall,我不会编写依赖于该代码的代码,但它可能是正常的。 – Jodrell 2013-05-03 15:08:54

回答

3

如果要测试“所有”值是否满足条件,则应使用扩展方法,而不是IEnumerable<T>而不是Any。我会写这样的:

var result = entity.Reports.All(x => 
{ 
    int result = 0; 
    return int.TryParse(x.Data, out result) && result > 0; 
}); 

我不相信你需要测试的空或空字符串,因为如果你在一个空或空字符串传递int.TryPrase将返回false。

+0

+1更简洁,但'result'初始化为'0'是不必要的。 – Jodrell 2013-05-03 15:14:12

+0

这正是我正在寻找的。是的,如果逻辑逆转,我的意思是所有虽然任何也可以使用。 – John 2013-05-03 16:01:53

0

你可以使用这个扩展,它试图将字符串解析到int并返回int?

public static int? TryGetInt(this string item) 
{ 
    int i; 
    bool success = int.TryParse(item, out i); 
    return success ? (int?)i : (int?)null; 
} 

那么这个查询工作:

bool all = entity.Reports.All(x => { 
    if(x.QuestionBlock != _question.QuestionBlockint) 
     return false; 
    int? data = x.Data.TryGetInt(); 
    return data.HasValue && data.Value > 0; 
}); 

或更具可读性(一点点效率较低):

bool all = entityReports 
    .All(x => x.Data.TryGetInt().HasValue && x.Data.TryGetInt() > 0 
      && x.QuestionBlock == _question.QuestionBlockint); 

该方法避免使用loc al变量为out参数,这是Linq-To-Objects中未记录的行为,并可能在将来停止工作。它也更具可读性。

+0

这种方法应该可以工作,并且具有代码更加可重用的优点。但是我没有尝试过,因为我没有在这个特定的项目中使用扩展方法。但我会记住它。 – John 2013-05-03 16:05:00

1
var allDataIsNatural = entity.Reports.All(r => 
    { 
     int i; 
     if (!int.TryParse(r.Data, out i)) 
     { 
      return false; 
     } 

     return i > 0; 
    }); 

Any将返回时,第一行是true但是,你说清楚,你想检查他们所有

+0

这个答案和Brian Balls一样,但是Jodrell说它不像Brian的球那么紧凑。非常感谢! – John 2013-05-03 16:03:10

相关问题