两个LINQ语句到一个等待的LINQ数据库查询(Optimize)

时间:2016-11-23 10:34:38

标签: c# entity-framework linq entity-framework-core

嘿大家我有一个有效的LINQ查询,但我想知道它是否可以进一步优化..

这就是我现在正在做的事情:

var selectionsAnimals = await this.context.SelectionAnimals
                                        .GroupBy(a => a.AnimalId)
                                        .ToListAsync();

var animalsSelections = selectionsAnimals
                         .Select(a => new AnimalsSelection
                                 {
                                     AnimalId = a.First().AnimalId,
                                     SelectionIds = a.Select(b => b.SelectionId)
                                                   .OrderBy(b => b)
                                                   .ToList()
                                 })
                         .ToList();

我想知道这两个LINQ语句是否可以合并并作为一个等待数据库的LINQ查询?

这是数据库实体:

public class SelectionAnimals
{
    public int Id { get; set; }
    public int AnimalId { get; set; }
    public int SelectionId { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
}

这是模型:

public class AnimalsSelection
{
    public int AnimalId { get; set; }
    public IList<int> SelectionIds { get; set; }
}

最后我将animalsSelection映射到IEnumerable<AnimalsSelection>(模型)

3 个答案:

答案 0 :(得分:4)

Michael Coxon通常是正确的,但即使是基本的查询构造处理,EF Core目前也非常不稳定。

所以(遗憾的是)最重要的问题是你使用的EF Core版本。这真的是一个试错过程。例如,在EF Core 1.1.0(发行版)中,Michael的构造不起作用,但以下等同于:

var animalsSelections = await db.SelectionAnimals
    .GroupBy(a => a.AnimalId)
    .Select(g => new AnimalsSelection
    {
        AnimalId = g.Key,
        SelectionIds = g.OrderBy(a => a.SelectionId)
                        .Select(a => a.SelectionId)
                        .ToList()
    })
    .ToListAsync();

答案 1 :(得分:1)

GroupBy会返回IQueryable,所以我很确定没有什么可以阻止你做...

var animalsSelections = await this.context.SelectionAnimals
                        .GroupBy(a => a.AnimalId)
                        .Select(a => new AnimalsSelection
                        {
                            AnimalId = a.First().AnimalId,
                            SelectionIds = a.Select(b => b.SelectionId)
                                            .OrderBy(b => b)
                                            .ToList()
                        })    
                        .ToListAsync();      

答案 2 :(得分:0)

确实没有比获取所有AnimalIdSelectionId更快的方式,然后将它们分组到客户端上。通过AnimalId排序然后使用自定义分组来假设项目按键排序可以略微改进。如果您还要订购SelectionIds

,实际上可能需要这样做

但正如您在评论中所说,您将拥有数百万条记录,这意味着查询将返回所有记录。

另一种选择是将SelectionIds连接到single comma-separated column,但这超出了LINQ的功能,所以你必须通过原始SQL。