nhibernate 3.3 linq扩展

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)));

原文地址:https://www.cnblogs.com/loswing/p/3414287.html