Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.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
C# 优化foreach循环_C#_Linq_Nhibernate - Fatal编程技术网

C# 优化foreach循环

C# 优化foreach循环,c#,linq,nhibernate,C#,Linq,Nhibernate,我有一些从数据库中提取记录的代码,然后我做一个简单的比较,检查记录是否匹配特定的模块和响应,然后使用计数并显示统计数据。不幸的是,当它访问数据库中超过1000条记录时,速度非常慢 在nHibernate中,我启用了延迟加载,这在最初的查询时间中有一点帮助,但当它进入这一部分时,它必须深入研究一点,这会减慢很多。我想问题是它从很多不同的表中提取数据来获得这些统计数据 从一些研究来看,似乎我应该能够通过编写linq语句而不是使用foreach循环来加快速度,但我已经尝试了几次,我并没有走多远。我想知

我有一些从数据库中提取记录的代码,然后我做一个简单的比较,检查记录是否匹配特定的模块和响应,然后使用计数并显示统计数据。不幸的是,当它访问数据库中超过1000条记录时,速度非常慢

在nHibernate中,我启用了延迟加载,这在最初的查询时间中有一点帮助,但当它进入这一部分时,它必须深入研究一点,这会减慢很多。我想问题是它从很多不同的表中提取数据来获得这些统计数据

从一些研究来看,似乎我应该能够通过编写linq语句而不是使用foreach循环来加快速度,但我已经尝试了几次,我并没有走多远。我想知道是否有人能帮我指出正确的方向。或者读一本好的Linq教程或书,因为我对这个话题知之甚少

我还看到,在类似的情况下,人们建议将作业放入sql server以填充另一个用于查找的表,但如果可能的话,我希望避免这种情况

这是代码

int modules = 0;
var sessionsWithPullHits = from session in m_sessions where session.PullHits.Count > 0 select session;

foreach (ISession<PullHitRecord, PushHitRecord> session in sessionsWithPullHits)
{
    foreach (var pullHit in session.PullHits)

    if ((pullHit.Module == _Module) && (pullHit.Response == _response))
    {
        modules++;
    }
}
int模块=0;
var sessionsWithPullHits=来自m_会话中的会话,其中session.PullHits.Count>0选择会话;
foreach(会话中的ISession会话带有PullHits)
{
foreach(会话中的var pullHit.PullHits)
if((pullHit.Module==\u Module)&&(pullHit.Response==\u Response))
{
模块++;
}
}
非常感谢任何人能给予的帮助。

LINQ:

var modules = (from session in m_sessions
               from pullHit in session.PullHits
               where pullHit.Module == _Module && pullHit.Response == _response
               select pullHit).Count();


注意,我不确定这将如何转换为SQL,但它是一条LINQ语句,因此应该可以工作。

如果您要做的只是获取会话计数,那么最好将_模块和_响应传递到SP,让DB进行计数,只返回计数


当然,如果你做的更多,这是不适用的。但却回馈了很多你不知道的决心;t使用效率不高。

@George Duckett的答案是用LINQ替换foreach代码。或者,您可以用流畅的语法表达他的相同查询,如下所示:

var modules = m_sessions
.SelectMany(session => session.PullHits, 
            (session, pullHits) => new { pullHits = pullHits })
.Where(session => session.pullHits.Module == _Module && 
                  session.pullHits.Response == _response)
.Count();
这不是很好,但最终的IL更小,可能会给你更好的结果。此外,这个版本提供的代码仍然稍小,可能带来一些好处。测试并查看:

var modules = m_sessions
  .Select(session => session.PullHits
      .Count(pullHit => pullHit.Module == _Module && 
                        pullHit.Response == _response))
  .Sum();

免责声明:我不支持过早优化,我只启用它:-)

我会研究如何管理表上的索引。向联接中使用的列添加索引会对性能产生显著影响。看这个


下面列出了其他SQL性能调优技巧:

感谢您的帮助,这非常适合替换foreach循环。我想我可能需要继续创建一个单独的表,因为在foreach循环中,性能只略微提高了一点。请考虑我的建议-很可能您的c#代码不是效率低下的部分。看看你的数据库代码。顺便说一下,这是一个写得很好的问题。欢迎来到stackoverflow!