带表达式参数的实体框架核心计数

时间:2019-12-02 16:14:22

标签: c# sql-server linq entity-framework-core expression

我正在尝试使用Entity Framework Core生成高性能的服务器端SQL查询,该查询将记录分为几组。例如,假设我有一张桌子:

CREATE TABLE ExOrders
(
    Id UNIQUEIDENTIFIER,
    Column1 VARCHAR(250),
    Column2 INT,
    ColumnN VARCHAR(500),
)

,结果应为选择查询:

select 
    count(<count1Condition>) as C1,
    count(<count2Condition>) as C2
from 
    ExOrders
where 
    <whereGenericCondition>

对于每个条件,我已经生成了一个Expression<Func<T, bool>>表达式。

到目前为止我尝试过的事情

  1. Linq Count()函数

    我正在尝试通过以下查询来获得上述结果:

Expression<Func<T, bool>> whereGenericCondition = GetExpression1();
Expression<Func<T, bool>> count1Condition = GetExpression2();
Expression<Func<T, bool>> count2Condition = GetExpression3();

var countRequestS1 = _dbcontext.Set<T>()
    .Where(whereGenericCondition)
    .GroupBy(s => 0)
    .Select(agg => new
                   {
                       C1 = agg.Count(count1Condition), // <- parameter error
                       C2 = agg.Count(count2Condition)  // <- parameter error
                   });

问题是Count扩展名不支持表达式参数。

错误:

  

参数2:无法从'System.Linq.Expressions.Expression >'转换为'System.Func '

  1. 带有Count()的Linq AsQueryable()函数

    我尝试在AsQueryable方法之前调用Count

var countRequestS2 = _dbcontext.Set<T>()
    .Where(whereGenericCondition)
    .GroupBy(s => 0) // <- from this point onward it is executed clientside
    .Select(agg => new
    {
        C1 = agg.AsQueryable().Count(count1Condition), 
        C2 = agg.AsQueryable().Count(count2Condition) 
    });

但是在这种情况下,它只是将所有数据放入应用程序中,并在本地进行处理(在我的情况下是无法接受的情况,因为有成千上万的行)。

  1. 预编译表达式

在使用它们之前,我还尝试过编译count1Conditioncount2Condition表达式:

var countRequestS3 = _dbcontext.Set<T>()
    .Where(whereGenericCondition)
    .GroupBy(s => 0) // <- from this point onward it is executed clientside
    .Select(agg => new
    {
        C1 = agg.Count(x => count1Condition.Compile()(x)),
        C2 = agg.Count(x => count2Condition.Compile()(x))
    });

但是在这种情况下,它只是将所有数据输入到应用程序中,与#2相同。

  1. 实施我自己的Count()

我最后的尝试是实现自己的CountAfterGroupByMethod,但遇到与通用T类型函数有关的错误。
在上下文模型构建器中崩溃:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasDbFunction(typeof(CountAfterGroupByExtensions).GetMethod("CountAfterGroupBy"), options =>
    {
        options.HasTranslation(CountAfterGroupByExpressionTranslator.Translate);
    });
    // where CountAfterGroupBy is 
    // public static int CountAfterGroupBy<TSource>(this IEnumerable<TSource> source, Expression<Func<TSource, bool>> predicate)
}

有错误:

  

System.ArgumentException:'DbFunction'CountAfterGroupByExtensions.CountAfterGroupBy'是通用的。不支持通用方法。'

在#3或#4中是否存在我看不到的缺陷?或者还有什么我可以尝试的?

1 个答案:

答案 0 :(得分:1)

计数不接受条件,对。所以放一个

.Where(count1Condition).Count() 

如果有计数,则在前面,并且有条件计数。