Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 访问空Linq结果非常慢_.net_Linq - Fatal编程技术网

.net 访问空Linq结果非常慢

.net 访问空Linq结果非常慢,.net,linq,.net,Linq,我的脚被林克弄湿了。我试图确定四个数据列中包含的不同值。所以,我从 var c1types = (from DataRow row in dtSource.Select("hasreq") where row["m"].ToInt() > 0 select new { col = row["m"] }).Distinct(); var c2types = (from DataRow row in dtSource.Select("

我的脚被林克弄湿了。我试图确定四个数据列中包含的不同值。所以,我从

var c1types = (from DataRow row in dtSource.Select("hasreq")
               where row["m"].ToInt() > 0
               select new { col = row["m"] }).Distinct();
var c2types = (from DataRow row in dtSource.Select("hasreq")
               where row["w"].ToInt() > 0
               select new { col = row["w"] }).Distinct();
var c3types = (from DataRow row in dtSource.Select("hasreq")
               where row["ag"].ToInt() > 0
               select new { col = row["ag"] }).Distinct();
var c4types = (from DataRow row in dtSource.Select("hasreq")
               where row["aq"].ToInt() > 0
               select new { col = row["aq"] }).Distinct();

foreach (var type in c1types.Union(c2types).Union(c3types).Union(c4types).Distinct())
{
  ...
}
这是可行的,但速度非常慢(4-5秒)。所以,我把下面的内容放在前面

MessageBox.Show(c1types.Count().ToString()); // 1 - immediate display
MessageBox.Show(c2types.Count().ToString()); // 1 - immediate display
MessageBox.Show(c3types.Count().ToString()); // 1 - immediate display
MessageBox.Show(c4types.Count().ToString()); // 0 - 4-5 seconds to display

对于我的示例数据,前三个选择中的每一个都返回一个不同的值(Count()==1)。第四个不返回任何值(Count()==0)。我不明白的是,为什么它会立即显示前三个计数,而第四个计数需要4-5秒才能显示。看来空泛的结果是经济放缓的原因。这里发生了什么,最好的解决方法是什么?

从您的代码中,我猜ToInt()是一种扩展方法。我很确定DataRow上的索引器会返回对象,我不记得对象定义了ToInt()

如果这是真的,ToInt可能会做一些降低性能的事情。也许它在做类似的事情

try { return Int32.Parse(arg); }
catch { return 0; }
如果Int32.Parse无法处理第[“aq”]行中的大多数值,则可能会导致速度缓慢-请检查调试窗口中是否存在异常。如果这是问题所在,您可以使用不会引发异常的Int32.TryParse来加快速度

如果我错了,你能提供更多的信息吗?什么是ToInt()

编辑:

我应该知道它是Convert.ToInt32,因为Int32.Parse接受一个字符串作为参数。我建议的解决办法如下

对Convert.ToInt32使用的批评:

您不应该捕获Convert.ToInt32中的异常。它抛出了所谓的“骨头”异常。不应该发生的例外情况。如果Convert.ToInt32中出现异常,则说明程序错误。您试图将某些内容转换为不代表Int32的Int32。考虑ToeTebug扩展方法的单元测试将是什么样子。您可以调用myPrizeSheep.ToInt()并获取0。将羊转换成数字有意义吗?接受Convert.Int32中的异常通常会导致以后的问题—在您的情况下,这是一个性能问题,但通常更糟—一个正确性问题

没有Convert.TryConvertInt32(对象)。不过有一个Int32.TryParse(字符串)。这是因为通常需要将用户输入的字符串解析为Int32。您可能希望他们输入的不是Int32-如果他们这样做,这不是例外情况-您可以告诉用户更正它-这是正常程序执行流程的一部分

如果您有一个对象,您必须知道它代表一个Int32,以便尝试转换它。如果传递给Convert.ToInt32的内容不代表Int32,则这是一种例外情况。我想不出有哪一个实例需要“尝试”将任何旧对象转换为Int32,BCL开发人员显然也不能

我认为ToInt不适合使用扩展方法。我通常使用扩展方法,这样就可以使用漂亮的管道转发样式语法将调用链接在一起。很少有实例需要将ToInt()链接到其他方法调用

因为ToInt所做的只是调用Convert.ToInt32并错误地接受任何异常。您最好在示例中使用Convert.ToInt32

解决方案:

考虑如何处理Linq查询中非整数的内容。在您的情况下,它们可能是null或DBNulls。您可能希望排除这些行,在这种情况下,您可以按照以下行编写一些内容:

var c4types = (from DataRow row in dtSource.Select("hasreq") 
               where row["aq"] != null && row["aq"] != DBNull.Value && row["aq"].ToInt() > 0 
               select new { col = row["aq"] }).Distinct();
该表达式的缺点是,最终得到的是对象列表,而不是Int32。您可以在最终选择中进行转换,但随后将进行两次转换。老实说,我的首选方式(如果您想要INT32的集合而不是对象)是:

var c4types = dtSource.Select("hasreq")
                      .Where(row => row["aq"] != null && row["aq"] != DBNull.Value)
                      .Select(Convert.ToInt32(row["aq"])
                      .Where(i => i > 0)
                      .Distinct();

在上面,我们首先去掉带有空值的行。然后我们转换我们知道有整数的行。然后我们去掉小于1的整数,最后得到一个唯一的整数集合。

您使用的是.net 3.5还是.net 4.0?我没有太多的数据表经验-是每个查询都会访问数据库后端,还是只是查询内存中的数据?如果是一个数据库,检查sql(sql profiler、linqpad等)可能有助于找出发生了什么(缺少索引?错误查询?等等),它在内存中--不涉及数据库。您完全正确,它是一个扩展方法,与您的代码类似,但使用Convert.ToInt32()。我会尝试你的建议,当我有机会,并将张贴我的发现在那个时候。谢谢@pahjoker-我应该知道是Convert.ToInt32!请参阅我上面的编辑-不要把我说的话当作个人的话,我只是想帮助您避免将来如果继续使用ToInt扩展方法可能出现的问题:)