nhibernate的sqlserver linq 全文检索搞了半天
方法一 ,扩展LinqToHqlGeneriatorsRegistry
http://www.cnblogs.com/xiarugu/archive/2012/06/02/nhiberate-linq-contains-freetext-search.html
http://www.cnblogs.com/lyj/archive/2010/08/11/inside-nh3-linq-extension-query.html
搞了半天都不行,后来找到
http://stackoverflow.com/questions/16318843/is-there-a-query-generator-or-extension-point-for-queryover-like-there-is-for-li
才知道 3.3 换了,query和queryover走的不是一条路。
Linq and QueryOver take different paths to sql:
QueryOver->Expression->Criteria \
Linq->LinqParser->Hql-->Sql
for Criteria there is NHibernate.Impl.ExpressionProcessor.RegisterCustomMethodCall(...);
弄半天 找到 nhibernate代码才知道怎么注册。。。。郁闷的心情啊。
https://github.com/nhibernate/nhibernate-core/blob/612d1b6874a0067f1a9ff1f052ad90f12ce21f1c/src/NHibernate/Criterion/RestrictionsExtensions.cs
https://github.com/nhibernate/nhibernate-core/blob/612d1b6874a0067f1a9ff1f052ad90f12ce21f1c/src/NHibernate/Criterion/RestrictionsExtensions.cs
最后,在人家基础上改的。。。
/// <summary> /// 扩展queryover /// </summary> public static class QueryOverExtensions { public static void Register() { ExpressionProcessor.RegisterCustomProjection(() => QueryOverExtensions.Day(default(DateTime)), QueryOverExtensions.ProcessDay); ExpressionProcessor.RegisterCustomProjection(() => QueryOverExtensions.Month(default(DateTime)), QueryOverExtensions.ProcessMonth); ExpressionProcessor.RegisterCustomProjection(() => QueryOverExtensions.Year(default(DateTime)), QueryOverExtensions.ProcessYear); ExpressionProcessor.RegisterCustomMethodCall(() => QueryOverExtensions.MyIsLike(string.Empty, string.Empty), QueryOverExtensions.ProcessIsLike); ExpressionProcessor.RegisterCustomMethodCall(() => QueryOverExtensions.ContainsSearch(string.Empty, string.Empty), QueryOverExtensions.ProcessContainsSearch); } public static bool MyIsLike(this string source, string pattern) { throw new Exception("QueryOverExtensions MyIsLike 只有数据库操作可用"); } /// <summary> /// 执行like操作 /// </summary> /// <param name="methodCallExpression"></param> /// <returns></returns> private static ICriterion ProcessIsLike(MethodCallExpression methodCallExpression) { ExpressionProcessor.ProjectionInfo projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); var values = (string)ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); return Expression.Sql(string.Format("{0} like '{1}'",projection.AsProjection(), values)); } /// <summary> /// 对字段进行模式搜索 /// </summary> /// <param name="source"></param> /// <param name="keyword">关键字</param> /// <returns></returns> public static bool ContainsSearch(this string source, string keyword) { throw new NotSupportedException("仅用于数据库搜索"); } private static ICriterion ProcessContainsSearch(MethodCallExpression methodCallExpression) { ExpressionProcessor.ProjectionInfo projection = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]); string values = (string)ExpressionProcessor.FindValue(methodCallExpression.Arguments[1]); return Expression.Sql(string.Format("contains( {0},'{1}')", projection.AsProjection(), values)); } public static Int32 Day(this DateTime dateTimeProperty) { return (dateTimeProperty.Day); } public static Int32 Month(this DateTime dateTimeProperty) { return (dateTimeProperty.Month); } public static Int32 Year(this DateTime dateTimeProperty) { return (dateTimeProperty.Year); } private static IProjection ProcessDay(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]).AsProjection(); return (Projections.SqlFunction("day", NHibernateUtil.Int32, property)); } private static IProjection ProcessMonth(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]).AsProjection(); return (Projections.SqlFunction("month", NHibernateUtil.Int32, property)); } private static IProjection ProcessYear(MethodCallExpression methodCallExpression) { IProjection property = ExpressionProcessor.FindMemberProjection(methodCallExpression.Arguments[0]).AsProjection(); return (Projections.SqlFunction("year", NHibernateUtil.Int32, property)); }
yy.QueryOver<xxx>().Where(c=>c.text.ContainsSearch("xx")).List();
yy.QueryOver<xxx>().Where(c=>c.text.MyIsLike("xx")).List();
yy.QueryOver<xxx>().Where(c=>c.dataime.Day()==DateTime.Now.Day).List();
最后===如果你还想偷懒点用
var query = QueryOver.Of<XXXXX>();
var qstr=" 1=1 and Contains(XXXX,'xxx')"
query.DetachedCriteria.Add( Expression.Sql(string.Format(qstr)));