GroupBy query and bit fields

假如想象 提交于 2019-12-11 00:04:35

问题


I am using entity framework core 2.1, I have a database context with an accessor for a model containing a boolean field represented as a non nullable bit field in an MS SQL database. I want to construct a query that evaluates in SQL efficiently that provides me a count of all rows in the table, and those with the bit column enabled.

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

In order to force the query to consume all rows, I use ToArray, however the group by, count and where clauses log they cannot be evaluated remotely.

Other attempts such as:

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

Produces two groups which I can later inspect but they fail to evaluate the bit column the same.

How can I generate a single expression that produces a new object with the count of all rows and the count of the subset which have the bit field enabled?


回答1:


The first technique (group by constant) worked well in EF6. Just instead of predicate based Count which has not direct SQL equivalent, using the conditional Sum produced a nice GROUP BY SQL.

Unfortunately, this doesn't translate to SQL in EF Core, even in 2.1.

Fortunately, combining it with intermediate projection produces the desired SQL translation in EF 2.1:

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();


来源:https://stackoverflow.com/questions/50916302/groupby-query-and-bit-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!