在NHibernate ICriteria中使用已注册全文搜索函数的问题求助
在NHibernate ICriteria中调用全文搜索函数的解决方案
我来帮你搞定这个问题!你已经正确注册了freetext和contains函数到自定义的CMSSQLDialect,接下来只需要在ICriteria中通过合适的方式调用这些函数即可,下面分步骤说明:
第一步:确认方言配置生效并优化函数注册
首先要确保你的CMSSQLDialect已经在NHibernate的配置文件(比如hibernate.cfg.xml或者app.config)中正确指定,不然注册的函数不会被NHibernate识别:
<property name="dialect">YourNamespace.CMSSQLDialect</property>
替换YourNamespace为你实际的命名空间。
另外建议优化一下函数注册代码,明确指定返回类型为布尔值(因为SQL Server的freetext和contains返回的是bit类型),这样后续调用更稳妥:
public class CMSSQLDialect : MsSql2008Dialect { public CMSSQLDialect() { RegisterFunction("freetext", new StandardSQLFunction("freetext", NHibernateUtil.Boolean)); RegisterFunction("contains", new StandardSQLFunction("contains", NHibernateUtil.Boolean)); } }
第二步:在ICriteria中调用全文搜索函数
这里提供两种常用的实现方式:
方式一:使用Restrictions.SqlRestriction
这种方式直接编写SQL片段,灵活且直观,适合快速实现:
// 初始化ICriteria实例 var store = sessionFactory.CreateCriteria(typeof(Comito.CMS.Domain.Entity.Document.Document)); // 使用contains函数搜索Content字段中的关键词 store.Add(Restrictions.SqlRestriction("contains({alias}.Content, ?)", "你的搜索关键词", NHibernateUtil.String)); // 或者使用freetext进行模糊语义搜索 // store.Add(Restrictions.SqlRestriction("freetext({alias}.Content, ?)", "你的搜索短语", NHibernateUtil.String)); // 执行查询 var results = store.List<Comito.CMS.Domain.Entity.Document.Document>();
这里的{alias}是NHibernate自动生成的表别名,会自动替换为实际的表别名,避免硬编码表名导致的问题。
方式二:使用Projections.SqlFunction
如果你更倾向于使用NHibernate的API风格,而非直接写SQL片段,可以用这种方式:
var store = sessionFactory.CreateCriteria(typeof(Comito.CMS.Domain.Entity.Document.Document)); // 使用contains函数 store.Add(Restrictions.Eq( Projections.SqlFunction( "contains", NHibernateUtil.Boolean, Projections.Property("Content"), // 对应实体的Content属性 Projections.Constant("你的搜索关键词") // 搜索值 ), true )); // 执行查询 var results = store.List<Comito.CMS.Domain.Entity.Document.Document>();
同样,freetext的用法只需要把函数名改成"freetext"即可。
重要前提检查
别忘了确认你的SQL Server数据库中,Document表对应的字段(比如Content)已经创建了全文索引,否则调用freetext或contains函数会抛出数据库异常。
内容的提问来源于stack exchange,提问作者user2435866
相关产品推荐
相关产品推荐

