我正在尝试使用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>>
表达式。
到目前为止我尝试过的事情
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 '
带有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)
});
但是在这种情况下,它只是将所有数据放入应用程序中,并在本地进行处理(在我的情况下是无法接受的情况,因为有成千上万的行)。
在使用它们之前,我还尝试过编译count1Condition
和count2Condition
表达式:
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相同。
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中是否存在我看不到的缺陷?或者还有什么我可以尝试的?
答案 0 :(得分:1)
计数不接受条件,对。所以放一个
.Where(count1Condition).Count()
如果有计数,则在前面,并且有条件计数。