I believe I'm misusing NHibernate in this example, but it seems to work without any problems. I'm using NHibernate to wire a class that is not related to a table using CreateSQLQuery. All that was needed was a map to a dummy table and the SQL had to return unique data for the Id property. For those with a lot of crazy SQL in thier code, this may help you move some of it to NHibernate.
Here is the map I used
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping namespace="SourceNet.Data.SQLObjects" xmlns="urn:nhibernate-mapping-2.0">
<class name="SourceNet.Data.SQLObjects.ClientOrderSummary1, SourceNet.Data" table="NOT_REAL_TABLE" lazy="false" mutable="false">
<id column="NO_ID" type="Int32" access="field.camelcase-underscore" name="Id">
<generator class="assigned" />
</id>
<property column="BULK_ORDER_ID" name="BulkOrderId" access="field.camelcase-underscore" type="Int32"/>
<property column="TRACKING_NUM" name="TrackingNum" access="field.camelcase-underscore" type="String"/>
<property column="TOTAL" name="Total" access="field.camelcase-underscore" type="Int32"/>
<property column="ORDERS_COMPLETED" name="OrdersCompleted" access="field.camelcase-underscore" type="Int32"/>
<property column="ORDERS_ON_HOLD" name="OrdersOnHold" access="field.camelcase-underscore" type="Int32"/>
<property column="ORDERS_IN_QA" name="OrdersInQa" access="field.camelcase-underscore" type="Int32"/>
<property column="TYPE" name="Type" access="field.camelcase-underscore" type="Int32"/>
<property column="CL_PERS_ID" name="ClientPersId" access="field.camelcase-underscore" type="Int32"/>
<property column="SYS_LOGIN_ID" name="SysLoginId" access="field.camelcase-underscore" type="Int32"/>
<property column="CL_DEPT_ID" name="ClDeptId" access="field.camelcase-underscore" type="Int32"/>
<property column="MIN_ORD_DT" name="MinOrderDate" access="field.camelcase-underscore" type="DateTime"/>
<property column="FIRST_NAME" name="FirstName" access="field.camelcase-underscore" type="String"/>
<property column="LAST_NAME" name="LastName" access="field.camelcase-underscore" type="String"/>
<property column="BY_FNAME" name="ByFname" access="field.camelcase-underscore" type="String"/>
<property column="BY_LNAME" name="ByLname" access="field.camelcase-underscore" type="String"/>
</class>
</hibernate-mapping>
And here is the way the object was used in a test unit. It was suprisingly fast.
Code:
[Test]
[Category("GetSQLObject Tests")]
public void SQL_NH_ClientOrderSummary1()
{
try
{
Console.WriteLine("Get SQL Object ClientOrderSummary1 for cl id 56");
DateTime start = DateTime.Now;
DateTime end;
Console.WriteLine("{0} Start\n", start.ToString(TIME_FORMAT));
string sql = "SELECT MAX(o.ORDER_ID) as {cos1.Id}, o.BULK_ORDER_ID as {cos1.BulkOrderId}, o.TRACKING_NUM as {cos1.TrackingNum}, COUNT(*) AS {cos1.Total}, "+
"SUM(CASE WHEN o.order_status_type_id IN (9, 11) THEN 1 ELSE 0 END) AS {cos1.OrdersCompleted}, "+
"SUM(CASE WHEN o.order_status_type_id = 10 THEN 1 ELSE 0 END) AS {cos1.OrdersOnHold}, "+
"SUM(CASE WHEN o.order_status_type_id IN (15, 19, 22, 23, 27) THEN 1 ELSE 0 END) AS {cos1.OrdersInQa}, "+
"MIN(o.CL_ORD_DT) AS {cos1.MinOrderDate}, 0 AS {cos1.Type}, bo.CL_PERS_ID as {cos1.ClientPersId}, "+
"cp.FIRST_NAME as {cos1.FirstName}, cp.LAST_NAME as {cos1.LastName}, bo.SYS_LOGIN_ID as {cos1.SysLoginId}, "+
"cp1.FIRST_NAME AS {cos1.ByFname}, cp1.LAST_NAME AS {cos1.ByLname}, o.CL_DEPT_ID as {cos1.ClDeptId} "+
"FROM [ORDER] as o "+
"INNER JOIN BULK_ORDER as bo ON (o.BULK_ORDER_ID = bo.BULK_ORDER_ID) "+
"LEFT OUTER JOIN CL_PERS as cp1 ON (bo.SYS_LOGIN_ID = cp1.SYS_LOGIN_ID) "+
"LEFT OUTER JOIN CL_PERS as cp ON (bo.CL_PERS_ID = cp.CL_PERS_ID) "+
"WHERE o.CL_ID = :Clid AND o.CL_ORD_DT > :ClOrdDtMin AND o.BULK_ORDER_ID IS NOT NULL "+
"GROUP BY o.BULK_ORDER_ID, o.TRACKING_NUM, bo.CL_PERS_ID, cp.FIRST_NAME, "+
"cp.LAST_NAME, bo.SYS_LOGIN_ID, cp1.FIRST_NAME, "+
"cp1.LAST_NAME, o.CL_DEPT_ID "+
"UNION "+
"SELECT MAX(o.ORDER_ID) as {cos1.Id}, 0 as {cos1.BulkOrderId}, '' as {cos1.TrackingNum}, COUNT(*) AS {cos1.Total}, "+
"SUM(CASE WHEN o.order_status_type_id IN (9, 11) THEN 1 ELSE 0 END) AS {cos1.OrdersCompleted}, "+
"SUM(CASE WHEN o.order_status_type_id = 10 THEN 1 ELSE 0 END) AS {cos1.OrdersOnHold}, "+
"SUM(CASE WHEN o.order_status_type_id IN (15, 19, 22, 23, 27) THEN 1 ELSE 0 END) AS {cos1.OrdersInQa}, "+
"MIN(o.CL_ORD_DT) AS {cos1.MinOrderDate}, 1 AS {cos1.Type}, 0 as {cos1.ClientPersId}, '' as {cos1.FirstName}, "+
"'' as {cos1.LastName}, 0 as {cos1.SysLoginId}, '' AS {cos1.ByFname}, '' AS {cos1.ByLname}, 0 as {cos1.ClDeptId} "+
"FROM [ORDER] as o "+
"WHERE o.CL_ID = :Clid AND o.CL_ORD_DT > :ClOrdDtMin AND o.BULK_ORDER_ID IS NULL "+
"ORDER BY {cos1.BulkOrderId}, {cos1.ClDeptId}";
IQuery qry = _mgr.Session.CreateSQLQuery(sql, "cos1", typeof(SourceNet.Data.SQLObjects.ClientOrderSummary1));
qry.SetInt32("Clid", 56);
qry.SetDateTime("ClOrdDtMin", new DateTime(2005, 6, 1));
IList results = qry.List();
Console.WriteLine("## results count: {0}", results.Count);
end = DateTime.Now;
Console.WriteLine("\n{0} Stop", end.ToString(TIME_FORMAT));
Console.WriteLine("======================================================");
Console.WriteLine("Total Time {0}\n", end.Subtract(start));
Console.WriteLine("BOrdId Total Type MinOrdDt Cmpltd OnHold InQa ClDpt ClPers SysLogin");
foreach(SourceNet.Data.SQLObjects.ClientOrderSummary1 cos in results)
{
Console.WriteLine("{0,6}{1,6}{2,8}{3,13}{4,8}{5,8}{6,8}{7,8}{8,8}{9,9} {10} [{11} {12} ({13} {14})]",
cos.BulkOrderId, cos.Total, cos.Type, cos.MinOrderDate.ToString("dd MMM yyyy"), cos.OrdersCompleted, cos.OrdersOnHold, cos.OrdersInQa,
cos.ClDeptId, cos.ClientPersId, cos.SysLoginId, cos.TrackingNum, cos.FirstName, cos.LastName, cos.ByFname, cos.ByLname);
}
end = DateTime.Now;
Console.WriteLine("\n{0} Stop", end.ToString(TIME_FORMAT));
Console.WriteLine("======================================================");
Console.WriteLine("Total Time {0}", end.Subtract(start));
} catch(Exception e) {
Console.WriteLine("TEST ERROR\n{0}", e.Message);
Console.WriteLine("STACK TRACE\n{0}", e.StackTrace);
Console.WriteLine("INNNER ERROR\n{0}", e.InnerException);
Assert.IsTrue(false, "SQL Object not obtained.");
}
}
The output
Quote:
Get SQL Object ClientOrderSummary1 for cl id 56
04:14:08:23812 Start
## results count: 11
04:14:08:48812 Stop
======================================================
Total Time 00:00:00.2499968
BOrdId Total Type MinOrdDt Cmpltd OnHold InQa ClDpt ClPers SysLogin
0 4 1 13 Jun 2005 4 0 0 0 0 0 [ ( )]
19494 172 0 13 Jun 2005 171 0 1 451 1896 2713 Adverse BPO Order_Impac Funding 2005-06-015 [Tim Knight (Tim Knight)]
...
04:14:08:50374 Stop
======================================================
Total Time 00:00:00.2656216