GroupBy查询和位字段

时间:2018-06-18 19:30:18

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

我正在使用实体框架核心2.1,我有一个数据库上下文,其中包含一个模型的访问器,该模型包含一个在MS SQL数据库中表示为非可空位字段的布尔字段。我想构建一个有效地在SQL中求值的查询,它为我提供表中所有行的计数,以及启用了位列的那些行。

var groups = await this.context.Models
    .AsNoTracking()
    .GroupBy(i => 1)
    .Select(g => new ViewModel
    {
        Count = g.Count(),
        Revoked = g.Count(p => p.IsRevoked)
    })
    .ToArrayAsync();

为了强制查询使用所有行,我使用ToArray,但是group by,count和where子句记录它们无法远程计算。

其他尝试,例如:

var query = await this.context.Models
        .AsNoTracking()
        .GroupBy(i => i.IsRevoked)
        .ToArrayAsync();

生成两个组,我稍后可以检查它们但是它们无法对位列进行相同的评估。

如何生成一个表达式,该表达式生成一个具有所有行计数的新对象以及启用了位字段的子集计数?

1 个答案:

答案 0 :(得分:2)

第一种技术(按常数分组)在EF6中运行良好。只是使用条件Count生成一个不错的Sum SQL而不是基于谓词的GROUP BY而不是直接SQL等价。

不幸的是,即使在2.1中,这也不会转换为EF Core中的SQL。

幸运的是,将它与中间投影相结合可以在EF 2.1中生成所需的SQL转换:

var counts = await this.context.Models
    .Select(e => new { Revoked = e.IsRevoked ? 1 : 0 })
    .GroupBy(e => 1)
    .Select(g => new ViewModel
    {
        Count = g.Count(),
        Revoked = g.Sum(e => e.Revoked)
    })
    .ToArrayAsync();