abp vnext 中使用Find方法报下面错误,这个肯定是ef core自身解析lambda的问题,不知道啥问题。
我的查询:
var order = await _paymentRecordRepository.FindAsync(o => o.OrderId == input.OrderNo && o.TotalAmount>0,false);
异常信息:
The LINQ expression 'DbSet<PaymentsRecord>
.Where(p => __ef_filter__p_0 || (Nullable<Guid>)EF.Property<Guid>(p, "TenantId") == __ef_filter__CurrentTenantId_1)
.Where(p => p.TotalAmount > 0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
abp vnext实现:
public override async Task<TEntity> FindAsync(
Expression<Func<TEntity, bool>> predicate,
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
return includeDetails
? await WithDetails()
.Where(predicate)
.SingleOrDefaultAsync(GetCancellationToken(cancellationToken))
: await DbSet
.Where(predicate)
.SingleOrDefaultAsync(GetCancellationToken(cancellationToken));
}
abp vnext中默认使用的是System.Linq.Dynamic.Core
中的Where.
不知道为啥就是>和<不能解析,==和!=就能解析。
代码如下:
public static IQueryable Where(this IQueryable source, LambdaExpression lambda)
{
Check.NotNull<IQueryable>(source, nameof (source));
Check.NotNull<LambdaExpression>(lambda, nameof (lambda));
Expression expression = DynamicQueryableExtensions.OptimizeExpression((Expression) Expression.Call(typeof (Queryable), nameof (Where), new Type[1]
{
source.ElementType
}, source.Expression, (Expression) Expression.Quote((Expression) lambda)));
return source.Provider.CreateQuery(expression);
}
这是因为单元测试使用的是Sqllte
数据库,对于decimal
类型需要进行转换。
参考:
if (IsDatabaseProvider(builder, options, EfCoreDatabaseProvider.MySql))
{
b.Property(p => p.FinishTime).HasColumnType("date");
b.Property(p => p.RealityAmount).HasColumnType("decimal(6,2)");
b.Property(p => p.CurrentTotalAmount).HasColumnType("decimal(6,2)").IsRequired();
b.Property(p => p.TotalAmount).HasColumnType("decimal(6,2)").IsRequired();
}
else if (IsDatabaseProvider(builder, options, EfCoreDatabaseProvider.SqlServer))
{
b.Property(p => p.FinishTime).HasColumnType("datetime");
b.Property(p => p.RealityAmount).HasColumnType("decimal(6,2)");
b.Property(p => p.CurrentTotalAmount).HasColumnType("decimal(6,2)").IsRequired();
b.Property(p => p.TotalAmount).HasColumnType("decimal(6,2)").IsRequired();
}
else if (IsDatabaseProvider(builder, options, EfCoreDatabaseProvider.Sqlite))
{
b.Property(p => p.FinishTime).HasColumnType("datetime");
b.Property(p => p.RealityAmount).HasConversion<double>();
b.Property(p => p.CurrentTotalAmount).HasConversion<double>().IsRequired();
b.Property(p => p.TotalAmount).HasConversion<double>().IsRequired();
}