嵌套集合属性上的 EF 核心总和不起作用



我的数据库具有以下结构:一个用户可以有多个帐户。一个账户可以有多次转账。

这是地图配置。我想在我的DTO中存储每个用户的信息以及他在每个帐户中的总储蓄。(下面的代码表示整个配置的一部分(。

this.CreateMap<User, UserTestModel>()
.ForMember(
utm => utm.AccountsSavings, 
options => options.MapFrom(u => u.Accounts
.Select(a => a.Transfers.Sum(t => t.Amount))
.ToList()));

我对数据库的查询(我使用的是带有Sqlite数据库的EF Core 3.1.3(如下所示:

var resultSet = await this._dbContext.Users
.ProjectTo<UserTestModel>(this.Mapper.ConfigurationProvider)
.ToListAsync(cancellationToken)
.ConfigureAwait(false);

但是,会引发以下异常。

*

System.InvalidOperationException:LINQ表达式的DbSet.其中(t=>EF.Property>((EntityShaperExpression:实体类型:帐户ValueBufferExpression:(ProjectionBindingExpression:EmptyProjectionMember(IsNullable:False),"Id"(!=空&amp;EF.Property>((EntityShaperExpression:实体类型:帐户ValueBufferExpression:(ProjectionBindingExpression:EmptyProjectionMember(IsNullable:False),"Id"(==EF.Property>(t,"AccountId"(.Sum(t=>t.Amount('无法翻译。以可翻译的形式重写查询,或者切换到客户端通过插入对AsEnumerable((,AsAsyncEnumerable((、ToList((或ToListAsync((。

*

这是我的代码的问题,还是我目前使用的一些框架(AutoMapper或EF Core(的问题?

编辑1:

我决定尝试从User实体手动收集该信息,但该代码导致了相同的异常,这意味着它不是Automapper的错:

var resultSet = await this._dbContext.Users
.Select(u => u.Accounts.Select(a => a.Transfers.Sum(t => t.Amount)).ToList())
.ToListAsync(cancellationToken)
.ConfigureAwait(false);

编辑2:

在EntityFrameworkCore的GitHub上创建了问题:https://github.com/dotnet/efcore/issues/20455

我能够用SQLite提供程序和Amount类型为decimal(与SqlServer提供程序配合使用很好(来复制它。

因此,您似乎遇到了EF Core文档中的以下SQLite查询限制:

SQLite本机不支持以下数据类型。EF Core可以读取和写入这些类型的值,并且还支持查询相等性(e.Property==value(。但是,其他操作,如比较和排序,则需要对客户端进行评估

  • 日期时间偏移
  • 小数
  • TimeSpan
  • UInt64

作为解决方法,请考虑接受文档中的建议:

Decimal类型提供了高精度。但是,如果您不需要这种精度,我们建议您使用double。您可以使用值转换器在类中继续使用十进制。

带有示例

modelBuilder.Entity<MyEntity>()
.Property(e => e.DecimalProperty)
.HasConversion<double>();           

最新更新