改进使用ToList()的Linq查询性能

时间:2015-10-21 13:37:03

标签: c# linq optimization linq-to-entities query-performance

@Rahul Singh在这篇文章中写的代码Convert TSQL to Linq to Entities

var result = _dbContext.ExtensionsCategories.ToList().GroupBy(x => x.Category)
                .Select(x =>
                    {
                        var files = _dbContext.FileLists.Count(f => x.Select(z => z.Extension).Contains(f.Extension));
                        return new
                        {
                            Category = x.Key,
                            TotalFileCount = files
                        };
                    });

但是这个代码在数据库上下文中使用时有问题,我们应该像这样使用ToList()来修复“在这个上下文中只支持原始类型或枚举类型”错误:

var files = _dbContext.FileLists.Count(f => x.Select(z => z.Extension).ToList().Contains(f.Extension));

问题是ToList()获取所有记录并降低性能,现在我编写了自己的代码:

    var categoriesByExtensionFileCount =
        _dbContext.ExtensionsCategories.Select(
            ec =>
                new
                {
                    Category = ec.Category,
                    TotalSize = _dbContext.FileLists.Count(w => w.Extension == ec.Extension)
                });

    var categoriesTOtalFileCount =
        categoriesByExtensionFileCount.Select(
            se =>
                new
                {
                    se.Category,
                    TotalCount =
                        categoriesByExtensionFileCount.Where(w => w.Category == se.Category).Sum(su => su.TotalSize)
                }).GroupBy(x => x.Category).Select(y => y.FirstOrDefault());

这段代码的性能更好,但它有很多代码,有关提高第一代码性能或减少第二代码行的任何想法:D

问候,Mojtaba

1 个答案:

答案 0 :(得分:0)

您应该具有从ExtensionCategories到FileLists的导航属性。如果您使用的是DB First,并且已在数据库中设置了外键约束,则应自动为您执行此操作。

如果您提供表格设计(或模型类别),它也会有很大帮助。

最后,您可以使用.ToList().Contains(...)重写.Any()来解决您的问题。类似的东西:

_dbContext.FileLists.Count(f => x.Any(z => z.Extension==f.Extension)));