NHibernate:如何使用 IQuery 将存储过程返回的 List<object> 转换为 List<Entity>?

NHibernate: how to transform List<object> returned by a stored procedure to List<Entity> using IQuery?

以下是我的存储过程:

CREATE PROCEDURE [dbo].[GetProducts_SP]
AS
BEGIN
    SELECT * FROM Products
END

这是我的代码:

// This code works
IList<ProductsEntity> list = session.QueryOver<ProductsEntity>().List<ProductsEntity>();

// This also works; I get expected data in `object`
string sql = null;
sql = "EXEC GetProducts_SP";
IQuery query = session.CreateSQLQuery(sql);
IList<object> listSP = query.List<object>();

由于session.QueryOver工作正常,实体定义或映射没有问题。这就是为什么我不发布 table 定义、实体 class 和映射。

如上代码所示,我从存储过程中正确获取了List<object>中的数据。
此外,我想将此 object 数据转换为实体。
为此,我使用此代码:

//Following fail
IList<ProductsEntity> listSPEntity = query
    .List<ProductsEntity>();

失败并出现异常:

System.ArgumentException: The value "System.Object[]" is not of type "ProductsEntity" and cannot be used in this generic collection.

这似乎很明显,因为 NHibernate 本身无法将 object 转换为实体。
所以我使用 transformer 来指导 NHibernate 如何用下面的代码做到这一点:

// This fails
IList<ProductsEntity> listSPEntity = query
    .SetResultTransformer(Transformers.DistinctRootEntity)
    .List<ProductsEntity>();

失败并出现异常:

System.ArgumentException: The value "True" is not of type "ProductsEntity" and cannot be used in this generic collection.

如何使用 IQuery 将存储过程返回的 List<object> 转换为 List<Entity>

Transformers.DistinctRootEntity 肯定不是这里的正确工具。该转换器期望结果中已经准备好的实体。如果没有 AddEntity 调用,您的过程会返回 object 数组,例如 new object[]{10, "Name", true}.

对于 ISQLQuery,您必须通过 AddEntity 调用手动注册返回的实体:

string sql = null;
sql = "EXEC GetProducts_SP";
var results = session.CreateSQLQuery(sql)
                .AddEntity(typeof(ProductsEntity).FullName)
                .List<ProductsEntity>();

请注意 AddEntityISQLQuery 中可用 CreateSQLQuery。它不适用于您在示例中使用的 IQuery