【问题标题】:Improve Linq query performance that use ToList()提高使用 ToList() 的 Linq 查询性能
【发布时间】:2016-01-20 12:58:58
【问题描述】:

这段代码由@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

【问题讨论】:

  • 如果您的代码有效并且您只是想“改进”它,您应该在 codereview.stackexchange.com 上发布
  • 不关心行数。它与性能无关。
  • @Tim Schmelter 我只想知道这样做是否更好
  • 我不太喜欢大型 LINQ 查询,这就是为什么对我来说,改进代码的第一步是重新开始 :)。在任何情况下,似乎.ToList().Contains(f.Extension) 位可以替换为.FirstOrDefault(z => z.Extension == f.Extension) != null 没有任何问题(假设给定类型可以为空)。

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


【解决方案1】:

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

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

最后,您可以使用.ToList().Contains(...).Any() 重写,这应该可以解决您的直接问题。比如:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    相关资源
    最近更新 更多