Nhibernate构建查询

时间:2018-02-14 12:54:13

标签: c# mysql nhibernate

我有一个在MySql中运行的查询,但我试图在Nhibernate中使用它,我面临问题,因为我是Nhibernate的菜鸟。

SELECT transaction_table.transaction_id,transaction_table.amount,transaction_table.reason,transaction_table.transaction_datetime,g.status,
       (CASE
         WHEN (transaction_table.user_from IN(0)) THEN 'Paypal'
        when  (transaction_table.user_from<>0) THEN u.user_fullname
       END)as user_name_from ,
       (CASE
         WHEN (transaction_table.user_to IN(0)) THEN 'Paypal'
        when  (transaction_table.user_to<>0) THEN us.user_fullname
       END)as user_name_to 
FROM   transaction_table 
left outer join users u on u.user_id=transaction_table.user_from 
left outer join users us on  transaction_table.user_to=us.user_id 
left join gateway_table g on g.gateway_table_id=transaction_table.gateway_table_id

这是查询,

var results = session.QueryOver<TransactionTable>(() => transactionAlias)
                .Left.JoinAlias(pr => pr.UserFrom, () => usersFromAlias.Id)
                .Left.JoinAlias(pr => pr.UserTo, () => usersToAlias.Id)
                .Left.JoinAlias(pr => pr.GatewayTableId, () => gatewayAlias.GatewayTableId)
                .SelectList(list => list
                    .Select(pr => pr.TransactionId)
                    .Select(pr => pr.Amount)
                    .Select(pr => pr.Reason)
                    .Select(pr => pr.TransactionDatetime)
                    .Select(pr => pr.GatewayTableId)
                    .Select(Projections.Conditional(
                        Restrictions.Eq(
                            Projections.Property(() => transactionAlias.UserFrom), 0),
                        Projections.Constant("Paypal"),
                        Projections.Property(() => usersFromAlias.FullName)
                    ))
                    .Select(Projections.Conditional(
                        Restrictions.Eq(
                            Projections.Property(() => transactionAlias.UserTo), 0),
                        Projections.Constant("Paypal"),
                        Projections.Property(() => usersToAlias.FullName)
                    )))
                .List<object[]>();

在此之后我无法弄清楚如何继续,这是我一直在实施的中途。我找不到可靠的东西,关于XML我的映射可能是关系未映射的问题,我无法想象该怎么做。

下面的映射:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="EWalletModule" namespace="EWalletModule">
  <!-- User Table -->
  <class name="Users" table="Users">
    <id name="Id" column="user_id" type="int">
      <generator class="native"></generator>
    </id>
    <property name="FullName" column="user_fullname" type="String"></property>
    <property name="Email" column="user_email" type="String"></property>
    <property name="Password" column="user_password" type="String"></property>
    <property name="CreatedDatetime" column="created_datetime" type="datetime"></property>
  </class>

  <!-- Transaction Table -->
  <class name="TransactionTable" table="transaction_table">
    <id name="TransactionId" column="transaction_id" type="int">
      <generator class="native"></generator>
    </id>
    <property name="GatewayTableId" column="gateway_table_id" type="int"></property>
    <property name="UserFrom" column="user_from" type="String"></property>
    <property name="UserTo" column="user_to" type="String"></property>
    <property name="Amount" column="amount" type="String"></property>
    <property name="Reason" column="reason" type="String"></property>
    <property name="TransactionDatetime" column="transaction_datetime" type="datetime"></property>
  </class>

  <!-- Gateway Table -->
  <class name="GatewayTable" table="gateway_table">
    <id name="GatewayTableId" column="gateway_table_id" type="int">
      <generator class="native"></generator>
    </id>
    <property name="Status" column="status" type="String"></property>
  </class>

  <!-- Wallet Table -->
  <class name="WalletTable" table="user_wallet">
    <id name="UserWalletId" column="user_wallet_id" type="int">
      <generator class="native"></generator>
    </id>
    <property name="UserId" column="user_id" type="int"></property>
    <property name="WalletBalance" column="wallet_balance" type="float"></property>
  </class>

  <!-- ManageWallet Table //For Admin -->
  <class name="ManageWalletTable" table="manage_wallet">
    <id name="ManageWalletId" column="manage_wallet_id" type="int">
      <generator class="native"></generator>
    </id>
    <property name="TransactionFee" column="transaction_fee" type="float"></property>
    <property name="WithdrawalFee" column="withdrawal_fee" type="float"></property>
    <property name="Tax" column="tax" type="float"></property>
  </class>
</hibernate-mapping>

表格像映射一样简单,但查询在Mysql工作台中工作,数据没问题,但不知道Nhibernate。 所以目前我得到了异常问题而且我知道这是错误的,但是无法弄清楚如何做到这一点,而且我不想用简单的SQL查询来做它,我很乐意去做Object Way。

感谢Stack-overflow社区。

2 个答案:

答案 0 :(得分:0)

JoinAlias方法最常用的重载有2个参数:导航属性的表达式和别名的表达式。

您不需要指定&#34; on&#34; condition - NHibernate将使用映射解决它。

为此,您必须为UserFromUserToGatewayTable添加导航属性。您可以保留旧属性,但将其重命名为UserFromId并将类型更改为int(并检查其他属性的类型:我猜Amount不应该是string,而是{{ 1}},decimaldouble)。 如果您不想或不想添加导航属性,那么您将不得不使用子查询,因为据我所知,如果没有映射导航属性,就无法在NHibernate中执行连接。

int

另外我建议你创建一个自定义Dto模型并使用ResultTransformer而不是只返回元组:

var results = session.QueryOver<TransactionTable>(() => transactionAlias)
                .Left.JoinAlias(pr => pr.UserFrom, () => usersFromAlias)
                .Left.JoinAlias(pr => pr.UserTo, () => usersToAlias)
                .Left.JoinAlias(pr => pr.GatewayTable, () => gatewayAlias)
                .SelectList(list => list
                    .Select(pr => pr.TransactionId)
                    .Select(pr => pr.Amount)
                    .Select(pr => pr.Reason)
                    .Select(pr => pr.TransactionDatetime)
                    .Select(pr => pr.GatewayTableId)
                    .Select(Projections.Conditional(
                        Restrictions.Eq(
                            Projections.Property(() => transactionAlias.UserFromId), 0),
                        Projections.Constant("Paypal"),
                        Projections.Property(() => usersFromAlias.FullName)
                    ))
                    .Select(Projections.Conditional(
                        Restrictions.Eq(
                            Projections.Property(() => transactionAlias.UserToId), 0),
                        Projections.Constant("Paypal"),
                        Projections.Property(() => usersToAlias.FullName)
                    )))
                .List<object[]>();

答案 1 :(得分:0)

我们需要的是关系映射。这由many-to-oneone-to-many表示。文档

5.1.11. many-to-one

6.1. Persistent Collections

所以,例如这个

<property name="UserFrom" column="user_from" type="String"></property>

应该是

<many-to-one name="UserFrom"   column="user_from_id" class="User" />
<property    name="UserFromId" column="user_from_id" type="Int32"  
                                    insert="false" update="false" />

我们引用此类用户的实体应具有属性

public virtual User UserFrom { get; set; }
public virtual int UserFromId { get; set; }

第二个不需要..但有时可能有用。

检查这些: