2011-05-04 47 views
11

更新的一類 - 在SONHibernate的 - 如何映射到沒有表(自定義的SQL查詢)

嗨,

我一直在學習NHibernate的編輯過的配置以提高可讀性 一兩天卻陷入了一點。

我需要能夠執行自定義存儲過程和使用的NHibernate將它們映射回領域類。

我有這種工作對於其中定義查詢映射回映射到數據庫表,如由許多NHibernate的例子的對象場景(參見下面的第一部分)。

然而在配置爲下面的第二部分,所述查詢提取從目標表中只有2列。由於這個原因,我創建了一個自定義對象,以便NHibernate有一些東西來映射返回值。自定義對象屬性與自定義過程的返回列名稱相同。

當我跑我的測試中,我得到這樣一個例外:

NHibernate.MappingException:沒有 留存爲: Proj.DataEntityTracker.Domain.Entities.CustomObject

所以我想在sql-query部分下映射對於NHibernate將返回值映射到對象屬性是不夠的。

所以我的問題是 - 如何建立一個映射其中有在數據庫中沒有相應的表,這樣我可以映射存儲過程到該對象的結果嗎?

 

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        assembly="Proj.DataEntityTracker.Domain" 
        namespace="Proj.DataEntityTracker.Domain.Entities"> 

    <class name="TrackedEntityProperty" table="TrackedEntityProperties"> 
    <id name="ID" type="Int32" unsaved-value="0"> 
     <generator class="native"></generator> 
    </id> 
    <property name="TrackedEntityID" /> 
    <property name="Name" /> 
    <property name="CreatedDate" /> 
    <property name="ChangedDate" /> 
    <property name="DataType" /> 
    <property name="CurrentValue" /> 
    <property name="RequestPropertyValueQuestion" /> 
    <property name="NullResponseIsAcceptable" /> 
    <property name="Duplication" /> 
    <property name="Frequency" /> 
    <property name="IsActive" /> 
    <property name="IsDeleted" /> 
    <property name="LastUpdateTaskGenerated" /> 
    <property name="LastUpdateTaskCompleted" /> 
    <property name="LastUpdateTaskCancelled" /> 
    </class> 

    <sql-query name="usp_GetTrackedEntityPropertiesDueForUpdate" > 
    <return alias="usp_GetTrackedEntityPropertiesDueForUpdate" class="TrackedEntityProperty"> 

     <return-property name="ID" column="ID" /> 
     <return-property name="TrackedEntityID" column="TrackedEntityID" /> 
     <return-property name="Name" column="Name" /> 
     <return-property name="CreatedDate" column="CreatedDate" /> 
     <return-property name="ChangedDate" column="ChangedDate" /> 
     <return-property name="DataType" column="DataType" /> 
     <return-property name="CurrentValue" column="CurrentValue" /> 
     <return-property name="RequestPropertyValueQuestion" column="RequestPropertyValueQuestion" /> 
     <return-property name="NullResponseIsAcceptable" column="NullResponseIsAcceptable" /> 
     <return-property name="Duplication" column="Duplication" /> 
     <return-property name="Frequency" column="Frequency" /> 
     <return-property name="IsActive" column="IsActive" /> 
     <return-property name="IsDeleted" column="IsDeleted" /> 
     <return-property name="LastUpdateTaskGenerated" column="LastUpdateTaskGenerated" /> 
     <return-property name="LastUpdateTaskCompleted" column="LastUpdateTaskCompleted" /> 
     <return-property name="LastUpdateTaskCancelled" column="LastUpdateTaskCancelled" /> 

    </return> 

    exec usp_GetTrackedEntityPropertiesDueForUpdate :TrackedEntityID 

    </sql-query> 

    <sql-query name="usp_SomeCustomSproc"> 
    <return alias="usp_SomeCustomSproc" class="CustomObject"> 

     <return-property name="ID" column="ID" /> 
     <return-property name="Name" column="Name" /> 

    </return> 

    exec usp_SomeCustomSproc :TrackedEntityID 

    </sql-query> 

</hibernate-mapping> 

回答

13

你在找什麼是預測。首先你需要修改你的查詢

<sql-query name="usp_SomeCustomSproc"> 
    <return-scalar column="Id" type="Int32"/> 
    <return-scalar column="Name" type="String"/> 

    exec usp_SomeCustomSproc :TrackedEntityID 

    </sql-query> 

然後在你調用它的代碼中指定一個結果轉換器。該AliasToBeanTransformer將採取列別名,並將它們映射到對象的屬性。

session.GetNamedQuery("usp_SomeCustomSproc") 
     .SetInt32("TrackedEntityID", 15) 
     .SetResultTransformer(Transformers.AliasToBean<CustomObject>()) 
     .List<CustomObject>() 
+0

謝謝,這是非常方便 – gb2d 2011-05-10 15:33:12

5

問題解決了,儘管NHibernate不希望你使用存儲過程。我張貼這個來幫助有同樣問題的人,因爲這個信息不容易!

初步博客與此幫助在這裏,雖然這個例子中映射的結果返回給一個標準的對象 - 表映射(這可能是你想要的)。我想結果映射回未在數據庫中的表表示的自定義對象:

http://forums.asp.net/t/1407518.aspx/1

所以,我創建了一個域類來保存存儲過程結果。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace MyProj.DataEntityTracker.Domain.Entities 
{ 
    public class DemoCustomSprocObj 
    { 
     public virtual Guid Guid { get; set; } 
     public virtual int ID { get; set; } 
     public virtual string Name { get; set; } 
    } 
} 

該類不必在SQL Server中相應的表,但我發現一個類定義確實需要創建(不帶表屬性),以避免「NHibernate的。MappingException:沒有persister:「類型錯誤。

還要注意,爲保存存儲過程結果而創建的域類需要一個ID字段,並且必須從數據庫返回。在這種情況下,我從SQL Server返回NEWID()並將映射類配置爲使用ID字段的GUID生成器。

CREATE PROCEDURE usp_DemoCustomSproc 
    @TrackedEntityID INT 
AS 
SET NOCOUNT ON 
BEGIN 
    SELECT NEWID() AS [Guid], 
      ID , 
      Name 
    FROM TrackedEntityProperties AS tep 
    WHERE TrackedEntityID = @TrackedEntityID 
END 

和映射類:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        assembly="MyProj.DataEntityTracker.Domain" 
        namespace="MyProj.DataEntityTracker.Domain.Entities"> 

    <!-- This mapping does not use a table, rather it exists to 
    allow the mapping of a stored procedure result back to a domain object. 
    Note the use of the GUID. An ID must be present and returned by the stored 
    procedure result, otherwise the object will not work with NHibernate. 
    Note also the absence of a table in the class tag. No table exists in 
    the database, but the mapping must exist to avoid "No persiter" errors. 

    Arguments are passed with the :Arg syntax. 

    It seems that NHibernate was not designed for use with stored procedures, 
    though it may be useful to be able to use them in some situations. This 
    is a means of doing so. 

    --> 

    <class name="DemoCustomSprocObj"> 
    <id name="Guid" type="guid" unsaved-value="00000000-0000-0000-0000-000000000000"> 
     <generator class="guid"></generator> 
    </id> 
    <property name="ID" /> 
    <property name="Name" /> 
    </class> 

    <sql-query name="usp_DemoCustomSproc"> 
    <return alias="usp_DemoCustomSproc" class="DemoCustomSprocObj"> 

     <return-property name="Guid" column="Guid" /> 
     <return-property name="ID" column="ID" /> 
     <return-property name="Name" column="Name" /> 

    </return> 

    exec usp_DemoCustomSproc :TrackedEntityID 

    </sql-query> 

</hibernate-mapping> 
+0

添加類固定我命名的查詢問題,以及。謝謝! – Alex 2011-11-20 16:51:34

相關問題