nHibernate - 使用namedQuery填充映射函数

时间:2013-03-26 10:44:33

标签: nhibernate fluent-nhibernate-mapping

我正在使用Fluent nHibernate作为我的数据层,我有一个主要通过nHibernate/LINQ填充的类,但在一些高级用法中,需要由存储过程填充。

我遇到的问题是类映射包含一个公式。当我调用nHibernate/LINQ函数时,底层变量按预期填充;当我调用GetNamedQuery()函数时,它会抛出一个错误:
值不能为空。参数名称:fieldname

对于NamedQuery,没有填充公式字段是完全合乎逻辑的(显然我想要一个子查询,而不是为返回的每条记录运行一个SQL语句!),但我想成为能够从存储过程填充公式值 - 或者至少查询不会抛出错误。

这可能吗?

地图

public class QuoteMap : ClassMap<Quote>
{
    public QuoteMap()
    {
        Id(x => x.Id).GeneratedBy.GuidComb();
        ...
        Map(x => x.ResponseCount).Formula("(SELECT COUNT(*) FROM QuoteResponse WHERE QuoteResponse.QuoteId = Id and QuoteResponse.Status = " + (int)QuoteResponseRepository.Status.Live + ")");
    }
}

存储库

// Works fine
public ICollection<Quote> GetAllByStatus(Status status)
{
    using (ISession session = NHibernateHelper.OpenSession())
    {
        var quoteQuery = (from quote in session.Query<Quote>()
                            where quote.Status == (int)status
                            select quote).ToList();

        return quoteQuery;
    }
}

// Dies horribly
public ICollection<Quote> GetListPendingByCompany(Guid companyId, Status status)
{
    using (ISession session = NHibernateHelper.OpenSession())
        return session.GetNamedQuery("QuoteGetListPendingByCompany")
                .SetGuid("Company_Id", companyId)
                .SetInt32("QuoteStatus", (int)status)
                .List<Quote>();
}

SQL

CREATE PROCEDURE [dbo].[QuoteGetListPendingByCompany] 
    @CompanyId uniqueidentifier,
    @QuoteStatus int
AS
BEGIN
    SET NOCOUNT ON;

    SELECT
            Quote.*,
            (
                SELECT 
                        COUNT(*) 
                FROM    QuoteResponse
                WHERE   QuoteResponse.QuoteId = Quote.Id
            ) AS ResponseCount  -- Needs to populate what is currently a formula field
    FROM    Quote
    -- ... code removed
END

StoredProcsMap.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="true" assembly="QMP.Data" namespace="QMP.Data.Model">
        <sql-query name="QuoteGetListPendingByCompany" callable="true">
        <return class="QMP.Data.Model.Quote, QMP.Data" />
        <![CDATA[ 
        exec dbo.QuoteGetListPendingByCompany @CompanyId=:Company_Id,@QuoteStatus=:QuoteStatus
        ]]>
    </sql-query>
</hibernate-mapping>

2 个答案:

答案 0 :(得分:0)

你不应该把公式放在流畅的映射中,这是因为你在namedquery中有它:

 Map(x => x.ResponseCount).Formula("(SELECT COUNT(*) FROM QuoteResponse WHERE QuoteResponse.QuoteId = Quote.Id and QuoteResponse.Status = " + (int)QuoteResponseRepository.Status.Live + ")");

只需将该字段映射为您对其他字段的处理方式,您就可以了:

Map(x => x.ResponseCount);

答案 1 :(得分:0)

在编辑完成后,我现在可以看到您要执行的操作,我不确定是否可能,如果使用调用SP的FORMULA,您是否要忽略NamedQuery列?

如果指定ResultTransformer会发生什么?

return session.GetNamedQuery("QuoteGetListPendingByCompany")
                .SetGuid("Company_Id", companyId)
                .SetInt32("QuoteStatus", (int)status)
                .SetResultTransformer(new AliasToBeanResultTransformer(typeof(Quote)))
                .List<Quote>();
}

虽然我怀疑它仍然是barf。