使用 Fluent NHibernate 设置类映射

标签 class stored-procedures fluent-nhibernate map fluent-nhibernate-mapping

我是使用 NHibernate 的新手,我很难在网上找到关于如何在不使用 XML 进行映射的情况下为存储过程创建 ClassMap 的清晰示例。我最近使用 Fluent 界面完成了这项工作,并想分享我学到的东西。

有问题的存储过程返回一个像这样的对象:

public class ProductCategoryNavigation
{
    public virtual int CategoryId { get; protected set; }
    public virtual int CategoryNodeId { get; set; }
    public virtual int ParentCategoryNodeId { get; set; }
    public virtual string Name { get; set; }
    public virtual string Title { get; set; }
    public virtual string SeoUrl { get; set; }
    public virtual bool IsActive { get; set; }
    public virtual int DisplayOrder { get; set; }
    public virtual int ProductCount { get; set; }
}

那么,如何创建 NHibernate 用来将存储过程的结果映射到该对象的 ClassMap?

最佳答案

ClassMap 如下所示:

public sealed class ProductCategoryNavigationMap : ClassMap<ProductCategoryNavigation>
{
    public ProductCategoryNavigationMap()
    {
        ReadOnly();

        // Set "CategoryId" property as the ID column. Without this, 
        // OpenSession() threw an exception that the configuration was invalid
        Id(x => x.CategoryId);
        Map(x => x.CategoryNodeId);
        Map(x => x.ParentCategoryNodeId);
        Map(x => x.Name);
        Map(x => x.Title);
        Map(x => x.SeoUrl);
        // The column name returned from the sproc is "VisibleInd", 
        // so this is here to map it to the "IsActive" property
        Map(x => x.IsActive).Column("VisibleInd"); 
        Map(x => x.DisplayOrder);
        Map(x => x.ProductCount);
    }
}

对存储过程的调用如下所示:

public List<NavigationViewModel> GetNavigationViewModel(int portalId, int localeId)
{
    const string sql = "EXEC [dbo].[Stored_Procedure_Name] @PortalId=:PortalId, @LocaleId=:LocaleId";
    return _session.CreateSQLQuery(sql)
                .AddEntity(typeof(ProductCategoryNavigation))
                .SetInt32("PortalId", portalId)
                .SetInt32("LocaleId", localeId)
                .List<ProductCategoryNavigation>()
                .Select(x => new NavigationViewModel
                                 {
                                     CategoryId = x.CategoryId,
                                     CategoryNodeId = x.CategoryNodeId,
                                     ParentCategoryNodeId = x.ParentCategoryNodeId,
                                     Name = x.Name,
                                     Title = x.Title,
                                     SeoUrl = x.SeoUrl,
                                     IsActive = x.IsActive,
                                     DisplayOrder = x.DisplayOrder,
                                     ProductCount = x.ProductCount
                                 })
                .ToList();
}

AddEntity 调用说明要将结果映射到哪个 Entity 类,它将使用上面定义的 ProductCategoryNavigationMap:

.AddEntity(typeof(ProductCategoryNavigation))

如果你仔细查看“sql”变量的值,你会看到两个参数:

  1. :PortalId
  2. :LocaleId

这些是通过调用:

.SetInt32("PortalId", portalId)
.SetInt32("LocaleId", localeId)

然后调用.List<ProductCategoryNavigation>()为我们提供了一个 IList,它允许我们使用 LINQ 来投影我们想要的任何东西。在这种情况下,我得到一个 NavigationViewModel 列表,它目前与 ProductCategoryNavigation 相同,但可以根据需要独立于实体进行更改。

我希望这可以帮助其他刚接触 NHibernate 的开发人员!

关于使用 Fluent NHibernate 设置类映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8619523/

相关文章:

c# - 在不使用 IUserType 查询数据库时如何防止 NHibernate SqlDateTime 溢出?

Java Scanner 类读取字符串

sql-server - 在存储过程中创建唯一 ID 以匹配旧数据

mysql - RowDataPacket 返回未定义的值

java - 使用 JDBC 将用户定义的表类型传递给 SQL Server 存储过程

sqlite - 使用 SQLite In Memory 配置测试 NHibernate 时,如何创建另一个数据库?

NHibernate, "On Delete Cascade",级联删除相关表中的行?

c++ - 在我自己的类中捕获并处理所有异常

php - 扩展类是否有 __construct() 等价物

c++ - 使用继承的 protected 成员 (C++) 时遇到问题