NHibernate 命名查询,每个子类都有表

Posted

技术标签:

【中文标题】NHibernate 命名查询,每个子类都有表【英文标题】:NHibernate Named query with table per subclass 【发布时间】:2012-06-12 11:19:56 【问题描述】:

我有一个项目,我们只使用命名查询来访问数据库。最近我们创建了新实体,我们计划按照子类模式映射表,所以我们按照文档创建了映射,一切看起来都很好,除了我们找不到如何在命名查询中定义表别名以便加载每个子类。

这是我们迄今为止所做的:

实体:

public class Gear 

    public virtual string Name  get; set; 

    public virtual string Slug  get; set; 


public class Pedal : Gear

    public virtual PedalTypeEnum PedalType  get; set; 

映射:

public class GearMap : ClassMap<Gear>

    public GearMap()
    
        Table("[Gear]");

        Id(m => m.Id).Column("Id");
        Map(m => m.Name).Column("[Name]");
        Map(m => m.Slug).Column("[Slug]");
    



public class PedalMap : SubclassMap<Pedal>


    public PedalMap() 
    

        Table("[Pedal]");
        KeyColumn("[Gear_Id]");

        Map(m => m.PedalType).Column("PedalType").CustomType(typeof(PedalTypeEnum));


    

我们尝试执行的查询是这个:

<sql-query name="myquery" >
<return alias="[Gear]" class="Gear" />
<![CDATA[
    SELECT 
        [Gear].*,
FROM 
        [Gear] [Gear]
]]>
</sql-query>

这会导致 nhibernate 生成以下 SQL:

SELECT 
     [Gear].[Id] as column1_12_0_, 
     [Gear].[Name] as column3_12_0_, 
     [Gear].[Slug] as column4_12_0_,          
     [Gear]_1_.PedalType as PedalType13_0_, 
     case 
        when [Gear]_1_.[Gear_Id] is not null then 1 
        when [Gear].[Id] is not null then 0 end as clazz_0_
FROM 
        [Gear] [Gear] 

如您所见,它正确检测子类并尝试加载仅属于子类的字段 PedalType 但由于没有别名为 [Gear]_1_. 的表,查询失败...

我们已尝试与踏板表进行连接,但我们无法找到正确的方法来设置别名,使其转换为[Gear]_1_.

有什么帮助吗?

【问题讨论】:

你有什么理由使用 SQL 而不是 HQL? 【参考方案1】:

这对我有用:

<sql-query name="myquery" >
  <return alias="Gear" class="Gear" />
  SELECT Gear.*
  FROM Gear Gear
  LEFT JOIN Pedal Gear_1_ on Gear.Id = Gear_1_.Gear_Id
</sql-query>

当然,您也可以只使用 HQL 而不是 SQL:

<query name="myhqlquery">
  from Gear
</query>

但是...我必须说这是 NHibernate 的一种非常低效的用法。您正在努力与框架抗争,而不是利用它的灵活性。

【讨论】:

抱歉,您能解释一下为什么这违反了框架吗?我正在使用 SQL,因为它似乎是调整 sql 查询以获得最佳性能同时保留框架的所有灵活性的最佳方式 :) 在需要时手工编写 SQL 绝对没问题。但是对每个查询都强制这样做是浪费时间。而且,在这种情况下,您需要付出很多努力才能使用所有其他方法开箱即用的东西(并且在许多情况下它可能会失败)。换句话说:你会在这里优化什么?您的实际分析是否表明这些优化是必要的? 使用 ORM 背后的想法是,准确地说,不必手工制作 SQL,同时利用 ORM 提供的更改跟踪、身份映射和其他功能。 SQL 查询功能是为了灵活性而提供的,因为有时您的查询不容易用 HQL、LINQ 或 Criteria 表达。但大多数时候其他方法更容易编码和维护。 好吧,随便你。但特别是对于多态查询,从长远来看,破解 NH 的内部约定可能不是最好的主意。 我通常把这些问题转过来。你有没有想过也许你是世界上唯一一个试图这样做的人?我并不是说你的架构是无效的,但完全有可能,因为没有其他人使用它,所以没有人花时间编写 NHibernate 代码来支持它。这就是开源的好处:您可以获得 NH 源代码,创建一个新的注入宏,该宏扩展为完整的joined-subclass 语句并将其贡献给社区。​​span>

以上是关于NHibernate 命名查询,每个子类都有表的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate + Fluent NHibernate 异常

通过子类结构在 nHibernate 表上使用 Linq 按类型查询

命名查询和继承

优化 NHibernate 查询

nhibernate中的命名查询错误

每个子类保存的流利 NHibernate 表