如何使用Npgsql EF Core比较货币数据?

问题描述

我正在使用一个带有“ money”列的表的数据库,我试图添加适用于该表的过滤器和搜索逻辑,但是当我尝试将数据与该列进行比较时出现异常。下面是我的功能:

private IEnumerable<AccountTransaction> GetPaymentData(Guid AccountId,IFinancialCriterion Criterion)
{
    IQueryable<BusinessTransactionCredit> payments = this.context.AccountPayments
                                                         .Include(X => X.Notes)
                                                         .Where(X => X.AccountId == AccountId);
    
    if (!ReferenceEquals(Criterion.EarliestTransactionDate,null))
    {
        payments = payments.Where(X => X.CreatedOn >= Criterion.EarliestTransactionDate);
    }
    
    if (!ReferenceEquals(Criterion.LatestTransactionDate,null))
    {
        payments = payments.Where(X => X.CreatedOn <= Criterion.EarliestTransactionDate);
    }
    
    if (!ReferenceEquals(Criterion.MinTransactionAmount,null))
    {
        payments = payments.Where(X => X.Amount >= Math.Abs(Criterion.MinTransactionAmount ?? 0));
    }
    
    if (!ReferenceEquals(Criterion.MaxTransactionAmount,null))
    {
        payments = payments.Where(X => X.Amount >= Math.Abs(Criterion.MaxTransactionAmount ?? 0));
    }
    
    return payments.Select(X => new AccountTransaction()
    {
        Id = X.Id,Amount = X.Amount,TransactionDate = X.CreatedOn
    }).ToArray();
}

每当我使用'Amount'属性指定用于评估比较的值时,都会出现以下异常:

Npgsql.PostgresException (0x80004005): 42883: operator does not exist: money >= numeric
   at Npgsql.NpgsqlConnector.<>c__DisplayClass160_0.<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Npgsql.NpgsqlConnector.<>c__DisplayClass160_0.<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async,Boolean isConsuming)
   at Npgsql.NpgsqlDataReader.NextResult()
   at Npgsql.NpgsqlCommand.ExecuteReaderAsync(CommandBehavior behavior,Boolean async,CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior)
   at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader()
   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.InitializeReader(DbContext _,Boolean result)
   at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.Execute[TState,TResult](TState state,Func`3 operation,Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
.
.
.
Exception data:
    Severity: ERROR
    SqlState: 42883
    MessageText: operator does not exist: money >= numeric
    Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
    Position: 154
    File: d:\pginstaller.auto\postgres.windows-x64\src\backend\parser\parse_oper.c
    Line: 731
    Routine: op_error

更新: 以下是BusinessTransactionCredit的代码段。使用Fluent API将“金额”属性定义为“金钱”

public class BusinessTransactionCredit 
{
    public Guid Id
    {
        get;
        set;
    }

    public Guid AccountId
    {
        get;
        set;
    }

    public Decimal Amount
    {
        get;
        set;
    }

    [Required]
    [MaxLength(100)]
    public String ReceiptData
    {
        get;
        set;
    }
    
    public DateTime CreatedOn
    {
        get;
        set;
    }

    [Required]
    [MaxLength(50)]
    public String CreatedBy
    {
        get;
        set;
    }

    public DateTime? LastModifiedOn
    {
        get;
        set;
    }

    [MaxLength(50)]
    public String LastModifiedBy
    {
        get;
        set;
    }

    public ICollection<PaymentNote> Notes
    {
        get;
        set;
    }
}

和IFinancialCriterion

public interface IFinancialCriterion
{
    Int32 PageNumber { get; }
    
    Int32 PageSize { get; }
    
    String SearchQuery { get; }
    
    String TransactionType{ get; }
    
    DateTime? EarliestTransactionDate{ get; }

    DateTime? LatestTransactionDate{ get; }

    Decimal? MinTransactionAmount{ get; }

    Decimal? MaxTransactionAmount{ get; }
}

解决方法

这是Npgsql EF Core提供程序中的错误,我已经打开https://github.com/npgsql/efcore.pg/issues/1467进行跟踪。对于下一个修补程序版本,应合并一个修补程序。

,

您必须尝试使用​​“双精度”属性类型,因为money属性与.net核心属性不匹配。

示例:

  • bigint ---> Int64
  • 布尔--->布尔
  • 字符--->字符串
  • 双精度---> Double
  • uuid ---> Guid

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...