NHibernate3剖析:Query篇之NHibernate.Linq自定义扩展

发布时间:2026/10/15 18:16:34
NHibernate3剖析:Query篇之NHibernate.Linq自定义扩展 Linq provider自定义扩展机制在NHibernate中几乎所有的面向对象查询语言(HQL、Criteria、QueryOver)都是可扩展的Linq也不例外。我们可以扩展自定义LINQ-provider并将LINQ扩展方法转换为SQL。下面看看NHibernate对外提供的Linq provider扩展机制。ILinqToHqlGeneratorsRegistry接口为Hql-Generators提供统一注册接口在Build SessionFactory的时候NHibernate注册提供的Hql-Generators。LinqToHqlGeneratorsRegistryFactory注册工厂提供Hql-Generators注册工厂默认注册NHibernate内置支持的NHibernate.Linq查询譬如DateTime类型提供的属性和方法、String类型提供的属性和方法、Queryable和Enumerable提供的方法。可以通过Configuration的linqtohql.generatorsregistry配置节或者Configuration类提供的LinqToHqlGeneratorsRegistry扩展方法注册实现ILinqToHqlGeneratorsRegistry接口自定义Linq provider扩展。DefaultLinqToHqlGeneratorsRegistry注册类默认NHibernate内置支持的NHibernate.Linq查询注册类继承ILinqToHqlGeneratorsRegistry接口。三种Hql-Generators接口IRuntimeMethodHqlGenerator对运行时方法注册ICollectionT集合的Contains方法带LinqExtensionMethodAttribute的扩展方法。IHqlGeneratorForMethod对方法Hql生成譬如Queryable和Enumerable类的Any、All、Min、Max、Contains方法string类型的StartsWith、EndsWith、Contains、Equals、ToLower、ToLowerInvariant、ToUpper、ToUpperInvariant、Substring、IndexOf、Replace方法和带LinqExtensionMethodAttribute的扩展方法NHibernate内部用于识别和转换Visitors类的方法。IHqlGeneratorForProperty对属性Hql生成譬如DateTime类型的Year、Month、Day、Hour、Minute、Second、Date属性string类型的Length属性。NHibernate内部用于识别和转换Visitors类的属性。两种Hql-Generators抽象类BaseHqlGeneratorForMethod​编辑BaseHqlGeneratorForMethod抽象类实现IHqlGeneratorForMethod接口。用于定义方法的Hql-Generators。例如NHibernate内置提供string类型StartWith()方法的Hql-Generators实现​编辑BaseHqlGeneratorForProperty​编辑BaseHqlGeneratorForProperty抽象类实现IHqlGeneratorForProperty接口。用于定义属性的Hql-Generators。例如NHibernate内置提供string类型Length属性的Hql-Generators实现​编辑知道了上面的内容相信你可以自定义一个Linq provider扩展了。Linq provider自定义扩展实现我们以String类型为例使用IsLike扩展方法对String类型扩展模仿SQL中的LIKE从句。1.Linq扩展方法使用IsLike扩展方法对String类型扩展代码如下//Code Snippets Copyright http://lyj.cnblogs.com/ public static class MyLinqExtensions { public static bool IsLike(this string source, string pattern) { pattern Regex.Escape(pattern); pattern pattern.Replace(%, .*?).Replace(_, .); pattern pattern.Replace(\[, [).Replace(\],]).Replace(\^, ^); return Regex.IsMatch(source, pattern); } }2.IsLike扩展方法的Hql-Generators实现创建完扩展方法之后就可以在内存中使用这个扩展了。但是我们需要NHibernate把他翻译成持久化查询(persistence-queries)即需要转换为SQL。像NHibernate内置的实现类似我们需要创建一个Generators//Code Snippets Copyright http://lyj.cnblogs.com/ public class IsLikeGenerator : BaseHqlGeneratorForMethod { public IsLikeGenerator() { SupportedMethods new[] {ReflectionHelper.GetMethodDefinition(() MyLinqExtensions.IsLike(null, null))}; } public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollectionExpression arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) { return treeBuilder.Like(visitor.Visit(arguments[0]).AsExpression(), visitor.Visit(arguments[1]).AsExpression()); }

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询