SUM() 和 AVERAGE() 包装在 CAST 中

SUM() and AVERAGE() are wrapped in CAST

我有一个tableTRANSACTIONS。它有点大所以有一部分:

CREATE TABLE [dbo].[TRANSACTIONS] 
(
    [transaction_ID]             UNIQUEIDENTIFIER NOT NULL,
    [transaction_number]         INT              IDENTITY (1000, 1) NOT NULL,
    [type_id]                    INT              NOT NULL,
    [source_currency_ID]         INT              NOT NULL,
    [target_currency_ID]         INT              NOT NULL,
    [source_value]               NUMERIC (14, 6)  NOT NULL,
    [target_value]               NUMERIC (14, 6)  NOT NULL,
    [user_account_source]        NVARCHAR (500)   NULL,
    [user_account_target]        NVARCHAR (500)   NULL,
    [user_wmid]                  VARCHAR (12)     NULL,
    [user_email]                 NVARCHAR (51)    NULL,
    [create_date]                DATETIME         CONSTRAINT [DF__transacti__creat__589C25F3] DEFAULT (getdate()) NOT NULL,
    [card_ID]                    INT              NULL,
    [payment_ID]                 NVARCHAR (80)    NULL,
    [enable_automation]          BIT              CONSTRAINT [DF__transacti__enabl__3AA1AEB8] DEFAULT ((1)) NOT NULL,
    [client_ID]                  UNIQUEIDENTIFIER NULL,
    [partner_ID]                 INT              NULL,
    [payment_type_ID]            INT              NOT NULL,
    [language_ID]                INT              NULL,
    [member_id]                  NUMERIC (18)     NULL,
    [desk_id]                    INT              NULL,
    [source_member_discount]     NUMERIC (18, 3)  NULL,
    [member_scores]              INT              NULL,
    [source_eps_fee_from_customer]  NUMERIC (18, 6)  NULL,
    [source_eps_fee]             NUMERIC (18, 6)  NOT NULL,
    [source_eps_fee_actual]      NUMERIC (18, 6)  NULL,
    [target_eps_fee]             NUMERIC (18, 6)  NOT NULL,
    [target_eps_fee_actual]      NUMERIC (18, 6)  NULL,
    [target_exchanger_fee]       NUMERIC(18, 6)   NOT NULL DEFAULT 0, 
    [exchange_rate]              NUMERIC (20, 9)  NULL,
    [source_master]              BIT              NULL,
    [manual_rate]                NUMERIC (20, 9)  NULL,
    [cb_cross_rate]              NUMERIC (20, 9)  NULL,
    [source_profit]              NUMERIC (18, 6)  NULL,
    [partner_reward]             NUMERIC (18, 6)  NULL,
    [source_service_profit]      NUMERIC (18, 6)  NULL,
    [is_individual]              BIT              NULL,
    [member_discount]            NUMERIC (18)     NULL,
    [scores]                     INT              NULL,
    [return_url]                 VARCHAR (300)    NULL,
    [err_return_url]             VARCHAR (300)    NULL,
    [add_scores]                 BIT              NULL,
    [mm_transaction_id]          NVARCHAR (80)    NULL,
    [lp_transaction_id]          NVARCHAR (50)    NULL,
    [masterbank_auth_ID]         NVARCHAR (50)    NULL,
    [cardtype]                   NVARCHAR (50)    NULL,
    [cl_num]                     INT              NULL,
    [cl_date]                    NVARCHAR (50)    NULL,
    [limit_check_day]            BIT              NULL,
    [limit_check_month]          BIT              NULL,
    [rapida_temp]                NVARCHAR (50)    NULL,
    [ecard_id]                   BIGINT           NULL,
    [card_payment_complete]      VARCHAR (4)      CONSTRAINT [DF_TRANSACTIONS_card_payment_complete] DEFAULT ('NO') NULL,
    [profit_in_rub]              NUMERIC (18, 4)  NULL,
    [cb_rub_rate]                NUMERIC (18, 4)  NULL,
    [check_wmid]                 VARCHAR (12)     NULL,
    [partner_rate]               NUMERIC (18, 4)  NULL,
    [wm_desc]                    VARCHAR (500)    NULL,
    [without_real]               BIT              NULL,
    [netex_point]                UNIQUEIDENTIFIER NULL,
    [secret_key]                 INT              NULL,
    [miniport_transfer]          BIT              NULL,
    [miniport_hold]              BIT              NULL,
    [hold_time]                  DATETIME         NULL,
    [is_from_widget]             BIT              NULL,
    [partner_reward_currency_id] INT              NULL,
    [user_phone]                 NVARCHAR (50)    NULL,
    [project_ID]                 INT              NOT NULL DEFAULT 2,
...

我通过 SELECT:

组合我需要的数据
return query
            .Where(x => x.CurrentStatus == TransactionStatus.PaymentSent)
            .GroupBy(x => new { SourceCurrency = x.SourceCurrency, TargetCurrency = x.TargetCurrency })
            .Select(x => new ProfitabilityReportEntry
            {
                SourceCurrencyCode = x.Key.SourceCurrency,
                TargetCurrencyCode = x.Key.TargetCurrency,
                TransactionsCount = x.LongCount(),
                TotalProfitRub = x.Sum(y => y.ProfitInRub),
                AverageProfitRub = x.Average(y => y.ProfitInRub),
                AverageAmountRub = x.Average(y => y.SourceValue * y.CbRubRate),
                TotalAmountRub = x.Sum(y => y.SourceValue * y.CbRubRate)
            })
            .ToList();

Class ProfitabilityReportEntry 是:

public class ProfitabilityReportEntry
{
    public PaymentCurrencyCode SourceCurrencyCode { get; set; }
    public PaymentCurrencyCode TargetCurrencyCode { get; set; }
    public long TransactionsCount { get; set; }
    public decimal? AverageAmountRub { get; set; }
    public decimal? AverageProfitRub { get; set; }
    public decimal? TotalAmountRub { get; set; }
    public decimal? AmountTurnoverPercent { get; set; }
    public decimal? TotalProfitRub { get; set; }
    public decimal? ProfitPercent { get; set; }
}

在映射的class Transaction(到TRANSACTIONS)属性中,上面查询中的总和和平均值也都是小数。

我的查询结果如下 SQL 语句:

select transactio0_.source_currency_ID as col_0_0_, transactio0_.target_currency_ID as col_1_0_, 
    cast(count(*) as BIGINT) as col_2_0_, 
    cast(sum(transactio0_.moneyback_profit_rub) as DECIMAL(19,5)) as col_3_0_,
    cast(avg(transactio0_.moneyback_profit_rub) as DECIMAL(19,5)) as col_4_0_, 
    cast(avg(transactio0_.source_value*transactio0_.cb_rub_rate) as DECIMAL(19,5)) as col_5_0_,
    cast(sum(transactio0_.source_value*transactio0_.cb_rub_rate) as DECIMAL(19,5)) as col_6_0_ 
    from TRANSACTIONS transactio0_ 
    where transactio0_.change_date>? and transactio0_.change_date<? and transactio0_.status_id=? group by transactio0_.source_currency_ID, transactio0_.target_currency_ID

问题是为什么会有转换,为什么 NHibernate 会生成它们?如何让 NH 摆脱它们?而且我认为它们也会影响性能。

为什么小数求和要转为小数?另外,如果我使用匿名类型强制转换仍然存在。

我的 Fluent NHibernate 版本是 2.0.3 和 NHibernate 5.2.1

例如 source_value 的类型为 NUMERIC (14, 6)cb_rub_rate 的类型为 NUMERIC (18, 4)。那么,您希望 source_value * cb_rub_rat 的结果是什么类型?

我认为,您应该使字段类型彼此相等。

但我认为它不影响性能。结果表达式中使用了所有 CAST 个运算符,因此它执行一次。