【问题标题】:How to create criteria query for given sql query如何为给定的 sql 查询创建条件查询
【发布时间】:2012-12-07 20:34:59
【问题描述】:

我正在为这个等效的 sql 查询创建一个 ICriteria 查询。

SELECT fCustomerID,
       ISNULL(
                (SELECT SUM(payinv.fAmount) AS Expr1
                 FROM dbo.tARPayment AS pay
                 INNER JOIN dbo.tARPaymentInvoice AS payinv ON pay.fPaymentID = payinv.fPaymentID
                 INNER JOIN dbo.tARInvoice AS inv ON payinv.fInvoiceID = inv.fARInvoiceID
                 WHERE (pay.fIsPosted = CASE pay.fPaymentType WHEN 'CM' THEN 0 WHEN 'EPD' THEN 0 ELSE 1 END)
                   AND (inv.fCustomerID <> dbo.tARCustomer.fCustomerID)
                   AND (pay.fCustomerID = dbo.tARCustomer.fCustomerID)), 0)
FROM dbo.tARCustomer
GROUP BY fCustomerID

但无论如何我都不知道如何生成等效的 nhibernate ICriteria 查询。

这是支付类

public partial class tARPayment 
{
    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see cref="tARPayment"/> class.
    /// </summary>
    public tARPayment()
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="tARPayment"/> class.
    /// </summary>
    /// <param name="fPaymentID">The fPaymentID of guid type.</param>
    public tARPayment(System.Guid fPaymentID)
    {
        this.ID = fPaymentID;
    }
    #endregion

    #region Properties

    /// <summary>
    /// Gets or sets payment id.
    /// </summary> 
    public virtual System.Guid fPaymentID { get; set; }

    /// <summary>
    /// Gets or sets fCustomerID.
    /// </summary> 
    public virtual System.Guid fCustomerID { get; set; }

    /// <summary>
    /// Gets or sets check number.
    /// </summary> 
    public virtual string fCheckNumber { get; set; }

    /// <summary>
    /// Gets or sets amount.
    /// </summary> 
    public virtual decimal fAmount { get; set; }       

    /// <summary>
    /// Gets or sets customer detail.
    /// </summary> 
    public virtual tARCustomer Customer { get; set; }

    public virtual IList<tARPaymentInvoice> PaymentInvoices { get; set; }        

    #endregion

    #region Methods
    /// <summary>
    /// partial class for payment.
    /// </summary>
    /// <returns>The method get code.</returns>
    public override int GetHashCode()
    {
        return ID.GetHashCode();
    }
    #endregion
}

这是一个发票类

public partial class tARInvoice 
{
    #region Constructor
    /// <summary>
    /// Initializes a new instance of the <see cref="tARInvoice"/> class.
    /// </summary>
    public tARInvoice()
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="tARInvoice"/> class.
    /// </summary>
    /// <param name="fARInvoiceID">The fARInvoiceID.</param>
    public tARInvoice(System.Guid fARInvoiceID)
    {
        this.ID = fARInvoiceID;
    }

    #endregion

    #region Properties
    /// <summary>
    /// Gets or sets fARInvoiceID.
    /// </summary> 
    public virtual Guid fARInvoiceID { get; set; }

    /// <summary>
    /// Gets or sets fCustomerID.
    /// </summary> 
    public virtual Guid fCustomerID { get; set; }


    /// <summary>
    /// Gets or sets Delivery Method.
    /// </summary> 
    public virtual string fDeliveryMethod { get; set; }

    /// <summary>
    /// Gets or sets Invoice Number.
    /// </summary> 
    public virtual int? fARInvoiceNumber { get; set; }



    public virtual tARCustomer Customer { get; set; }

    public virtual IList<tARPaymentInvoice> PaymentInvoices { get; set; }        

    #endregion

    #region Methods
    /// <summary>
    /// retrieve Hash Code.
    /// </summary>
    /// <returns>The method get code.</returns>
    public override int GetHashCode()
    {
        return ID.GetHashCode();
    }
    #endregion
}

这是一个付款发票类。

public partial class tARPaymentInvoice 
{
    #region Constructor
    /// <summary>
    /// Initializes a new instance of the <see cref="tARPaymentInvoice"/> class.
    /// </summary>
    public tARPaymentInvoice()
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="tARPaymentInvoice"/> class.
    /// </summary>
    /// <param name="fPaymentInvoiceID">The Invoice ID.</param>   
    public tARPaymentInvoice(System.Guid fPaymentInvoiceID)
    {
        this.ID = fPaymentInvoiceID;
    }
    #endregion

    #region Properties
    /// <summary>
    /// Gets or sets fPaymentInvoiceID.
    /// </summary>
    public virtual System.Guid fPaymentInvoiceID { get; set; }

    /// <summary>
    /// Gets or sets fPaymentID.
    /// </summary>
    public virtual System.Guid fPaymentID { get; set; }

    /// <summary>
    /// Gets or sets fInvoiceID.
    /// </summary>
    public virtual System.Guid fInvoiceID { get; set; }           


    /// <summary>
    /// Gets or sets tARPayment.
    /// </summary>
    public virtual tARPayment Payment { get; set; }

    /// <summary>
    /// Gets or sets tARInvoice.
    /// </summary>
    public virtual tARInvoice Invoice { get; set; }

    #endregion

    #region Methods
    /// <summary>
    /// get hash codes.
    /// </summary>        
    /// <returns>The hash code.</returns>
    public override int GetHashCode()
    {
        return ID.GetHashCode();
    }
    #endregion
}

【问题讨论】:

  • 我更新了示例类。
  • 你有进步吗?与 HQL 或 LINQ 相比,专门使用 Criteria API 是否重要?
  • 不,我没有取得任何成功。我们可以使用 HQL,但不确定所有数据库的 HQL 是否相同,或者哪个更好
  • HQL 和 LINQ(内部执行与 HQL 相同)对于所有数据库都是相同的。至少在我看来 LINQ 似乎更自然。
  • 我们匈牙利人为世界付出了这么多...我现在看到 SQL 感到非常自豪! ;)

标签: c# hibernate nhibernate fluent-nhibernate nhibernate-criteria


【解决方案1】:

我建议不要将上述查询转换为 LINQ 或 HQL,而是将查询转换为视图,然后使用 NHibernate 查询该视图。

SQL

CREATE VIEW vCustomerAmount AS
SELECT fCustomerID,
       ISNULL(
                (SELECT SUM(payinv.fAmount) AS Expr1
                 FROM dbo.tARPayment AS pay
                 INNER JOIN dbo.tARPaymentInvoice AS payinv ON pay.fPaymentID = payinv.fPaymentID
                 INNER JOIN dbo.tARInvoice AS inv ON payinv.fInvoiceID = inv.fARInvoiceID
                 WHERE (pay.fIsPosted = CASE pay.fPaymentType WHEN 'CM' THEN 0 WHEN 'EPD' THEN 0 ELSE 1 END)
                   AND (inv.fCustomerID <> dbo.tARCustomer.fCustomerID)
                   AND (pay.fCustomerID = dbo.tARCustomer.fCustomerID)), 0) [Amount]
FROM dbo.tARCustomer
GROUP BY fCustomerID

C# DTO

public class CustomerAmount
{
    public int fCustomerID { get; set; }
    public decimal Amount { get; set; }
}

查询

List<CustomerAmount> customerAmounts = session.Query<CustomerAmount>().ToList();

【讨论】:

    【解决方案2】:

    不确定 nHibernate,但是这个重写的查询是否有助于获得相同的答案,并且可以更轻松地运行?

    SELECT T.fCustomerID,
           coalesce( SUM( payinv.fAmount ), 0 ) as SumAmt
       FROM 
          dbo.tARCustomer T
             JOIN dbo.tARPayment AS pay
                ON T.fCustomerID = pay.fCustomerID 
                AND pay.fIsPosted = CASE pay.fPaymentType 
                                    WHEN 'CM' THEN 0 
                                    WHEN 'EPD' THEN 0 
                                    ELSE 1 END
                 JOIN dbo.tARPaymentInvoice AS payinv 
                   ON pay.fPaymentID = payinv.fPaymentID
                   INNER JOIN dbo.tARInvoice AS inv 
                      ON payinv.fInvoiceID = inv.fARInvoiceID
                     AND inv.fCustomerID <> T.fCustomerID
       GROUP BY 
          T.fCustomerID
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-07
      • 2013-07-09
      • 2012-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-19
      • 2021-05-19
      相关资源
      最近更新 更多