2011-05-04 53 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

相关问题