从大型ienumerable获取计数

bqjvbblv  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(373)

我有一个由3个内部连接表组成的数据集,其中包含来自mysql数据库的大约18000条记录。我的函数应该是获取所有相关数据,然后根据用户提供的一些参数对其进行过滤,然后返回应用过滤器的项目计数。
当我使用标准数据读取器时,这确实很好,但是我刚刚将应用程序移到使用实体框架来尝试和改进性能,为此我使用lazyloadingproxies—我相信这与问题有关。
我的主要职能是
获取所有数据项
(对于每个参数)克隆所有数据项
获取筛选项的计数
代码如下所示

var EventsLogged = context.EventLogs.Where(x => x.Event.GameId == request.GameId
                                     && (!request.EventId.HasValue || x.EventId == request.EventId.Value)
                                     && (!request.StartTime.HasValue || x.Created >= request.StartTime.Value)
                                     && (!request.EndTime.HasValue || x.Created <= request.EndTime.Value));

if (EventsLogged.Count() <= 0)
{
    response.AddErorrMessage("No data found for Event.");
}
else
{
    //Some other stuff happens here not related to do with working on the parameters

    IEnumerable<EventLogs> filteredEvents = EventsLogged;
    filteredEvents = FilterResultsSet(filteredEvents, parametervalue);

    return filteredEvents.Select(x => x.UserId).Distinct().Count();
}

这个函数运行得很好,过滤也很好,然后当我们点击select.distinct().count()时,处理时间就快到了疯狂的地步——我等了大约20分钟才放弃。
在我的输出窗口中,我可以看到sql的各个部分被输出,就好像此时实际正在执行查询一样,但一次只能执行一条记录。
从我已经看过的内容来看,有一些关于获取ienumerable计数的规则,要获取计数,必须对它进行计算。
因为我不关心这个查询中的任何内容,只关心计数,所以有什么方法可以实现这一点-或者我需要重新考虑我的整个策略。

jei2mxaa

jei2mxaa1#

在遵循这两条评论的建议后,我试图从搜索中删除可为空的项目。然而,这并没有带来更多的优化。
正如怀疑的那样,是lazyloadingproxies导致了问题-当运行.select()实体框架并试图填充我的数据集时,它没有我真正想要的上下文,所以它试图解析并获取大量数据;其中还包含一个关系循环,即4个表通过外键链接在一起-所以我想它是在尝试一次解决所有问题。
当我删除延迟加载时,我必须使用.include()和.thenclude()选项指定要解析的导航属性。
工作代码如下

List<EventsLogged> EventsLogged = context.EventLogs
                                            .Include(log => log.Session)
                                            .Include(log => log.EventParameterValues)
                                                .ThenInclude(val => val.EventParameter)
                                            .Where(x => x.Event.GameId == request.GameId).ToList();

相关问题