NHibernate - 如何映射到没有表的类(用于自定义 sql 查询)
更新 - 编辑配置以提高可读性 在SO中
Hi》中,
我已经学习 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>
Update - Edited config for readability
in SO
Hi,
I've been learning NHibernate for a day or two but getting stuck on one point.
I need to be able to execute custom stored procedures and use NHibernate to map them back to domain classes.
I have this working for the scenario where the custom query maps back to a object that maps to a database table, as shown by many a nhibernate example (See first section below).
However in the config for the second section below, the query pulls only 2 columns from the target table. For this reason, I have created a custom object so that NHibernate has something to map the return values to. The custom object properties have the same name as the return columns from the custom procedure.
When I run my tests I get an exception like:
NHibernate.MappingException: No
persister for:
Proj.DataEntityTracker.Domain.Entities.CustomObject
So I guess the mapping under sql-query section is not enough for NHibernate to map the return values to the object properties.
So my question is - how do I set up a mapping for which there is no equivalent table in the database such that I can map the results of a stored procedure to that object?
<?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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在寻找的是预测。首先,您需要修改查询,
然后在调用它的代码中指定结果转换器。 AliasToBeanTransformer 将获取列别名并将它们映射到对象的属性。
What you're looking for are projections. First of all you need to modify your query
Then in the code where you call it you specify a result transformer. The AliasToBeanTransformer will take column aliases and map them to properties on the object.
问题已解决,尽管 NHibernate 显然不希望您使用存储过程。我发布此信息是为了帮助其他遇到同样问题的人,因为获得此信息并不容易!
最初的博客对此提供了帮助,尽管此示例将结果映射回标准对象 - 表映射(这可能是您想要的)。我想将结果映射回数据库中没有表表示的自定义对象:
http://forums.asp.net/t/1407518.aspx/1
因此,我创建了一个域类来保存存储过程结果。
这个类不必在 SQL Server 中具有相应的表,尽管我发现确实需要创建一个类定义(没有表属性)以避免“NHibernate.MappingException: No persister for:”类型错误。
另请注意,为保存存储过程结果而创建的域类需要一个 ID 字段,并且必须从数据库返回该字段。在本例中,我从 SQL Server 返回 NEWID() 并将映射类配置为对 ID 字段使用 GUID 生成器。
和映射类:
Problem solved, although it seems apparent that NHibernate doesn’t want you using stored procedures. I am posting this to help others with the same issue, as this information was not easy to come by!
Initial blog that helped with this was here, though this example mapped the result back to a standard object - table mapping (which may be what you want). I wanted to map the result back to a custom object that did not have a table representation in the database:
http://forums.asp.net/t/1407518.aspx/1
So, I created a domain class to hold the stored procedure result.
This class does not have to have a corresponding table in SQL server, although I found that a class definition does need to be created (with no table attribute) so as to avoid “NHibernate.MappingException: No persister for:” type errors.
Note also that the domain class that is created to hold the stored procedure result needs an ID field, and this must be returned from the database. In this case, I returned NEWID() from SQL Server and configured the mapping class to use the GUID generator for the ID field.
And the mapping class: