Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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# 使用for循环和linq查询提高性能_C#_Performance_Nhibernate_Queryover - Fatal编程技术网

C# 使用for循环和linq查询提高性能

C# 使用for循环和linq查询提高性能,c#,performance,nhibernate,queryover,C#,Performance,Nhibernate,Queryover,我有一个对象数组,我需要根据某些参数从数据库中获取一些对象信息,我正在实现: public IList<object[]> GetRelevants(Registro[] records) { List<object[]> returnList = new List<object[]>(); using (var session = SessionFactory.OpenStatelessSession())

我有一个对象数组,我需要根据某些参数从数据库中获取一些对象信息,我正在实现:

public IList<object[]> GetRelevants(Registro[] records)
    {
        List<object[]> returnList = new List<object[]>();
        using (var session = SessionFactory.OpenStatelessSession())
        {
            for (int kr = 0; kr < records.Length; kr++)
            {
                Registro record = records[kr];
                var query = session.QueryOver<Registro>()
                                    .Where(sb => sb.Asunto == record.Asunto)
                                    .And(sb => sb.FechaInicial == record.FechaInicial)
                                    .And(sb => sb.FechaFinal == record.FechaFinal)
                                    .And(sb => sb.FoliosDesde == record.FoliosDesde)
                                    .And(sb => sb.FoliosHasta == record.FoliosHasta)
                                    .And(sb => sb.TomoNumero == record.TomoNumero)
                                    .And(sb => sb.TomoTotal == record.TomoTotal)
                                    .And(sb => sb.SerieCodigo == record.SerieCodigo)
                                    .And(sb => sb.Caja == record.Caja)
                                    .And(sb => sb.Carpeta == record.Carpeta).SelectList(list => list
                                      .Select(p => p.Id)
                                      .Select(p => p.NuevaCaja)
                                      .Select(p => p.NuevaCarpeta)
                                      .Select(p => p.Periodo));

                var result = query.SingleOrDefault<object[]>();
                returnList.Add(result);
            }
        }
        return returnList;
    }
public IList GetRelevants(Registro[]记录)
{
List returnList=新列表();
使用(var session=SessionFactory.openstatesession())
{
for(int kr=0;krsb.Asunto==record.Asunto)
和(sb=>sb.fechainical==record.fechainical)
和(sb=>sb.FechaFinal==record.FechaFinal)
和(sb=>sb.FoliosDesde==record.FoliosDesde)
和(sb=>sb.FoliosHasta==record.FoliosHasta)
和(sb=>sb.TomoNumero==record.TomoNumero)
和(sb=>sb.tomotot总计==record.tomotot总计)
和(sb=>sb.SerieCodigo==record.SerieCodigo)
和(sb=>sb.Caja==record.Caja)
和(sb=>sb.ru毯a==record.ru毯a)
.选择(p=>p.Id)
.选择(p=>p.NuevaCaja)
.选择(p=>p.nua)
.选择(p=>p.Periodo));
var result=query.SingleOrDefault();
返回列表。添加(结果);
}
}
退货清单;
}
然而,在记录中,有超过10000件物品,所以NHibernate大约需要10分钟来完成


有什么方法可以提高这方面的性能吗?

一个好的解决方案可能是放弃此任务的NHibernate,将数据插入临时表,然后加入该临时表

然而,如果您想使用NHibernate,您可以通过不发出10000个单独的查询(这就是现在正在发生的事情)来加快速度。您可以尝试将查询分解为大小合理的块:

List<object[]> ProcessChunk(
    IStatelessSession session,
    int start,
    IEnumerable<Registro> currentChunk)
{
    var disjunction = Restrictions.Disjunction();

    foreach (var item in currentChunk)
    {
        var restriction = Restrictions.Conjunction()
            .Add(Restrictions.Where<Registro>(t => t.Asunto == item.Asunto))
            /* etc, calling .Add(..) for every field you want to include */

        disjunction.Add(restriction);
    }

    return session.QueryOver<Registro>()
        .Where(disjunction)
        .SelectList(list => list
            .Select(t => t.Id)
            /* etc, the rest of the select list */
        .List<object[]>()
        .ToList();
}
等等。如果500是每个区块的大小,则每个查询将返回多达500条记录

这仍然不会很快。我的本地测试将运行时间缩短了一半

根据数据库引擎的不同,您可能会很快遇到可以传递的最大数量的参数。您可能必须使用
chunkSize
才能使其正常工作


如果使用临时表并抛弃NHibernate,您可能会在几秒钟内完成此操作。

“Doc我这样做很痛苦,”…您是返回上一次迭代的
结果还是将其保存在任何地方?for循环的意义是什么?那10000条Registro记录来自哪里?来自同一数据库?在这种情况下,查询应在数据库上运行…在发布类似问题时请显示所有相关代码..这使得其他人很难看到您在此循环中所做的事情例如
例如记录是如何定义和/或填充的..2您使用的方法签名是什么样的。。如果有的话,返回类型是什么。。还有,一旦分配了
result
,您将如何处理它….?对不起,我只是问了一个不完整的问题,现在我只是在测试性能,然后是的,我必须返回一个IList结果,并在每次迭代中将其添加到此IList,以生成一个分号分隔的文件,10000个或更多的Registro对象是从第三方csv生成的文件读取的。提前感谢,我将实现这一点,我将保持联系,告诉您艺术状态。。。jejeI刚刚看了一篇关于you@Andrew Whitaker的优秀博客,我称之为“解释良好的工作”,其中有非常清晰的例子和最重要的主题:从NHibernate到SQL原生语句的翻译,我非常喜欢这个博客!感谢Andrew Whitaker的创作最终我发现@Andrew Whitaker answer非常有用,非常感谢,它对我来说效果很好,在7分钟内处理了1.000.072条记录!。
const int chunkSize = 500;   

for (int kr = 0; kr < records.Length; kr += chunkSize)
{
    var currentChunk = records.Skip(i).Take(chunkSize);

    resultList.AddRange(ProcessChunk(session, i, currentChunk));
}