sql-server-2008 – 用于SQL Server 2008全文索引’包含’关键字
副问题[/!--empirenews.page--]
我以为在实现LinqToHql天生器类时我穷乏一些根基的对象. 我已行使此注册行使自界说方言乐成注册了SQL Server 2008包括的查询: RegisterFunction("contains",new StandardSQLFunction("contains",null)); 我只有一个类要查询全文索引: public class SearchName { public virtual Guid Id {get; set;} public virtual string Name {get; set;} // this is the search field } contains函数在HQL中正常事变: var names = Session.CreateQuery("from SearchName where contains(Name,:keywords)") .SetString("keywords","john") .List(); 而且天生的SQL是美满的: select searchname0_.Id as Id4_,searchname0_.Name as Name4_ from Search_Name searchname0_ where contains(searchname0_.Name,'john' /* @p0 */) 下一个挑衅是实现Linq到HQL天生器: public class MyLinqtoHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry { public MyLinqtoHqlGeneratorsRegistry() { this.Merge(new ContainsGenerator()); } } public class ContainsGenerator : BaseHqlGeneratorForMethod { public ContainsGenerator() { SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition<SearchName>(d => d.Name.Contains(String.Empty)) }; } public override HqlTreeNode BuildHql(MethodInfo method,System.Linq.Expressions.Expression targetObject,ReadOnlyCollection<System.Linq.Expressions.Expression> arguments,HqlTreeBuilder treeBuilder,IHqlExpressionVisitor visitor) { return treeBuilder.MethodCall("contains",visitor.Visit(targetObject).AsExpression(),visitor.Visit(arguments[0]).AsExpression() ); } } } 挪用这样的要领: var namesLinq = Session.Query<SearchName>().Where(x=> x.Name.Contains("john")).ToList(); 不幸的是,这好像没有包围内置的Contains要领,而且天生的SQL是错误的: select searchname0_.Id as Id4_,searchname0_.Name as Name4_ from Search_Name searchname0_ where searchname0_.Name like ('%' + 'john' /* @p0 */ + '%') 是否无法包围默认的Contains要领,可能我只是犯了一个愚笨的错误? PS – 我正在行使NHibernate 3.3.1.4000 办理要领好的,我终于搞清晰了!起首,我想法从我的设置中删除了注册码: ... .ExposeConfiguration(cfg => { cfg.LinqToHqlGeneratorsRegistry<MyLinqtoHqlGeneratorsRegistry>(); ... } 其次,不要试图包围现有的Linq举动.我将Contains扩展要领移动到全文类. 第三,正确构建Hql树. 对付其他实行实现SQL 2008自由文本包括搜刮的人来说,这是完备的实现: public static class DialectExtensions { public static bool Contains(this SearchName sn,string searchString) { // this is just a placeholder for the method info. // It does not otherwise matter. return false; } } public class MyLinqtoHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry { public MyLinqtoHqlGeneratorsRegistry() : base() { RegisterGenerator(ReflectionHelper.GetMethod(() => DialectExtensions.Contains(null,null)),new ContainsGenerator()); } } public class ContainsGenerator : BaseHqlGeneratorForMethod { string fullTextFieldName = "Name"; public ContainsGenerator() : base() { SupportedMethods = new[] { ReflectionHelper.GetMethodDefinition(() => DialectExtensions.Contains(null,null)) }; } public override HqlTreeNode BuildHql(MethodInfo method,IHqlExpressionVisitor visitor) { // cannot figure out how to interrogate the model class to get an // arbitrary field name... // perhaps the RegisterGenerator() call above could be used to pass a // property name to the ContainsGenerator constructor? // in our case,we only have one full text searchable class,and its // full-text searchable field is "Name" HqlExpression[] args = new HqlExpression[2] { treeBuilder.Ident(fullTextFieldName).AsExpression(),visitor.Visit(arguments[1]).AsExpression() }; return treeBuilder.BooleanMethodCall("contains",args); } } 要使上述事变正常,您必需声明并行使自界说方言: public class CustomMsSql2008Dialect : NHibernate.Dialect.MsSql2008Dialect { public CustomMsSql2008Dialect() { RegisterFunction( "contains",null) ); } } 然后您可以这样行使新的包括搜刮: var namesLinq = Session.Query<SearchName>().Where(x => x.Contains("john")).ToList(); …而获得的SQL是美满的! (至少假如你只有一个表,你正在举办全文搜刮) 编辑:更新实现支持高出一个FULLTEXT’包括’搜刮每个查询. (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |