在Fluent NHibernate中使用Oracle和QueryOver时,我遇到了算术溢出错误,因为SelectAvg正在输出一个带有许多小数位的值。我认为,由于小数位数过多,因此无法在C#中将此数字映射为双精度值。
这是我的NHibernate代码:
var queryOverResult = _session.QueryOver<PurchasedVehicle>(() => purchasedVehicle)
.JoinAlias(() => purchasedVehicle.FinancialSnapshot, () => financialSnapshot)
.Where(pv => pv.Created >= startDate)
.Where(pv => pv.Created <= endDate)
.SelectList(list => list
.SelectCount(pv => pv.Dealer.Id).WithAlias(() => topPerformersKpiDto.PurchaseCount)
.SelectAvg(() => financialSnapshot.LikeMineDaysSupply).WithAlias(() => topPerformersKpiDto.AverageLms)
.SelectAvg(() => financialSnapshot.CostToMarket).WithAlias(() => topPerformersKpiDto.AverageCtm)
.SelectGroup(pv => pv.Dealer.Id))
运行时出现此错误:
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Arithmetic operation resulted in an overflow.",
"ExceptionType": "System.InvalidCastException",
"StackTrace": " at Commons.Data.XDataReader.GetValueSafely(Int32 i)\r\n at NHibernate.Type.NullableType.NullSafeGet(IDataReader rs, String name)\r\n at NHibernate.Loader.Criteria.CriteriaLoader.GetResultColumnOrRow(Object[] row, IResultTransformer customResultTransformer, IDataReader rs, ISessionImplementor session)\r\n at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)\r\n at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)\r\n at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters)",
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Arithmetic operation resulted in an overflow.",
"ExceptionType": "System.OverflowException",
"StackTrace": " at Oracle.DataAccess.Types.DecimalConv.GetDecimal(IntPtr numCtx)\r\n at Oracle.DataAccess.Client.OracleDataReader.GetDecimal(Int32 i)\r\n at Oracle.DataAccess.Client.OracleDataReader.GetValue(Int32 i)\r\n at Commons.Data.XDataReader.GetValueSafely(Int32 i)"
}
topPerformersKpiDto.AverageLms和topPerformersKpiDto.AverageCtm都是double类型。
public class TopPerformersKpiDto : IDto
{
public Guid DealerId { get; set; }
public int PurchaseCount { get; set; }
public double? AverageLms { get; set; }
public double? AverageCtm { get; set; }
}
NHibernate产生此oracle sql:
SELECT y0_,
y1_,
y2_,
y3_
FROM (SELECT Count(this_.dealerid) AS
y0_,
Avg(Cast(financials1_.likeminedayssupply AS DOUBLE PRECISION)) AS
y1_,
Avg(Cast(financials1_.costtomarket AS DOUBLE PRECISION)) AS
y2_,
this_.dealerid AS
y3_
FROM omni.purchasedvehicles this_
INNER JOIN omni.purchasedvehiclesnapshots financials1_
ON this_.id = financials1_.purchasedvehicleid
WHERE this_.created >= :p0
AND this_.created <= :p1
GROUP BY this_.dealerid
ORDER BY y0_ desc)
WHERE rownum <= :p2
运行此命令时,平均属性的值类似于“ 78.58731195652173913043478260869565217391”。
我正在尝试的一种解决方法是将平均值转换为“ Decimal(0,3)”,如下所示:
y0_,
Cast(Avg(Cast(financials1_.likeminedayssupply AS DOUBLE PRECISION)) as Decimal(10,3)) AS
y1_,
Cast(Avg(Cast(financials1_.costtomarket AS DOUBLE PRECISION)) as Decimal(10,3)) AS
当我在sql中执行此操作时,一切正常。但是,我不知道如何在NHibernate的QueryOver上下文中做到这一点。
编辑:看起来错误是我遇到的错误与这里的错误相同:https://community.oracle.com/thread/329112我不知道如何在NHibernate中截断我的号码。
这也似乎与我尝试在.NET中代表NUMBER(38)的问题有关:Which .NET data type is best for mapping the NUMBER Oracle data type in NHibernate?