所以我在我的dabatase中有一个表值函数,它基于几个参数执行一些繁重而复杂的查询,并返回例如三列:OrderId
,SomeCalc1
,SomeCalc2
现在为了将其转换为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。
答案 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列名;您可能需要根据命名约定对它们进行调整。