I'm using Fluent nHibernate
for my data layer, and I have a class that is mostly populated through nHibernate/LINQ
but in a few advanced usages, needs to be populated by a stored procedure.
The problem I have is the class mapping includes a Formula. When I call a nHibernate/LINQ
function, the underlying variable is populated as expected; when I call the GetNamedQuery()
function it throws an error:
Value cannot be null. Parameter name: fieldname
It's completely logical that for a NamedQuery
, the Formula field isn't populated (obviously I want a subquery here rather than a SQL statement run for every single record returned!), but I'd like to be able to populate the Formula value from the stored procedure - or at least the query not to throw an error.
Is this possible?
Map
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 + ")");
}
}
Repository
// 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>