渴望从NHibernate中的表值函数加载相关实体

时间:2018-01-29 16:35:51

标签: c# linq nhibernate linq-to-nhibernate

所以我在我的dabatase中有一个表值函数,它基于几个参数执行一些繁重而复杂的查询,并返回例如三列:OrderIdSomeCalc1SomeCalc2

现在为了将其转换为NHibernate,我发现的唯一解决方案是使用命名查询。我的映射如下:

<class name="OrderWithSomeExtraInfo">
  <id name="OrderId" column="OrderId"/>
  <many-to-one name="Order" update="false" insert="false">
    <column name="OrderId"/>
  </many-to-one>
  <property name="SomeCalc1" column="SomeCalc1" update="false" insert="false"/>
  <property name="SomeCalc2" column="SomeCalc2" update="false" insert="false"/>
</class>


<sql-query name="GetOrdersWithSomeCalc">
 <return class='MyDomain.OrderWithSomeExtraInfo, MyDomain' alias='o'/>

 <![CDATA[

  SELECT F.SomeCalc1 AS {o.SomeCalc1}, F.SomeCalc2 AS {o.SomeCalc2}, F.OrderId AS {o.OrderId}
  FROM [dbo].[funcSomething] ( :Param1, :Param2, :StartDate, :EndDate ) AS F

 ]]>
</sql-query>

然后在代码中我调用以下内容:

 IEnumerable<OrderWithSomeExtraInfo> query =
         Session.GetNamedQuery("GetOrdersWithSomeCalc")
         .SetString("Param1", p1)
         .SetString("Param2", p2)
         .SetDateTime("StartDate", StartDate)
         .SetDateTime("EndDate", EndDate)
         .Future<OrderWithSomeExtraInfo>();

我想要做的是,在代码中,还需要获取OrderWithSomeExtraInfo的Order属性,以及一些链接的多对一属性。像这样:

  IEnumerable<OrderWithSomeExtraInfo> query =
         Session.GetNamedQuery("GetOrdersWithSomeCalc")
         .SetString("Param1", p1)
         .SetString("Param2", p2)
         .SetDateTime("StartDate", StartDate)
         .SetDateTime("EndDate", EndDate)
         .Fetch(owse => owse.Order)
         .ThenFetch(o => o.Customer)
         .Future<OrderWithSomeExtraInfo>();

但是我找不到这样做的方法,因为它不是NHibernate LINQ查询。因此,当源是本机SQL查询时,我不知道如何急切获取,也不知道如何将函数映射到LINQ或QueryOver API。

2 个答案:

答案 0 :(得分:0)

首先我要道歉,因为我不太了解NHibernate,但由于没有人回答,我会尽我所能分享一些我发现的信息。

这是NHennate创作者Aende的一篇非常好的文章。他解释了如何将存储过程与自定义SQL和生成关系的实体一起使用。 https://ayende.com/blog/1692/using-nhibernate-with-stored-procedures

看起来如果您想要关联订购和客户(&lt; - 这就是我所理解的),那么您还必须对其进行建模(或将其映射到您的xml中)。

在文章的中间有你可能正在寻找的东西。这篇文章中的<loader query-ref="allSalariesForEmployee"/>类似于应该负责关联。如果关联不是来自存储过程,这也应该是可能的。

我希望这有帮助,我确实理解你的问题是正确的。

答案 1 :(得分:0)

尝试将您的命名查询更改为以下内容:

  <sql-query name="GetOrdersWithSomeCalc">
    <![CDATA[
      SELECT *
      FROM [dbo].[funcSomething] (:Param1,:Param2,:StartDate,:EndDate ) as F
      JOIN [dbo].[Orders] O ON F.OrderId = O.OrderId
      JOIN [dbo].[Customers] C ON O.CustomerId = C.CustomerId
     ]]>
    <return alias='f' class='MyDomain.OrderWithSomeExtraInfo, MyDomain'/>
    <return-join alias='o' property='f.Order' />
    <return-join alias='c' property='o.Customer' />
  </sql-query>

这应该'急切地'填充你的对象(使用你的第一个例子,不需要.Fetch或.FetchNext语句)。我推断了表名和Id列名;您可能需要根据命名约定对它们进行调整。