我的数据库具有以下结构:一个用户可以有多个帐户。一个账户可以有多次转账。
这是地图配置。我想在我的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"(!=空&;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>();