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 异常