Predicate提取

Predicate提取


用EF或者其他ORM的经常会有传入如入参数的,
System.Linq.Expressions> predicate
这时如果要拼接条件的话需要个PredicateBuilder类的,以下代码是从CoreShop源码中提取的
using System;
using System.Linq;
using System.Linq.Expressions;

namespace CoreCms.Net.Model.Entities.Expression
{
    public static class PredicateBuilder
    {
        public static Expression<Func<T, bool>> True<T>()
        {
            return f => true;
        }

        public static Expression<Func<T, bool>> False<T>()
        {
            return f => false;
        }

        public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second,
            Func<System.Linq.Expressions.Expression, System.Linq.Expressions.Expression,
                System.Linq.Expressions.Expression> merge)
        {
            // build parameter map (from parameters of second to parameters of first)  
            var map = first.Parameters.Select((f, i) => new {f, s = second.Parameters[i]})
                .ToDictionary(p => p.s, p => p.f);

            // replace parameters in the second lambda expression with parameters from the first  
            var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);

            // apply composition of lambda expression bodies to parameters from the first expression   
            return System.Linq.Expressions.Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
        }

        /// <summary>
        ///     扩展啦
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="first"></param>
        /// <param name="second"></param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first,
            Expression<Func<T, bool>> second)
        {
            return first.Compose(second, System.Linq.Expressions.Expression.AndAlso);
        }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first,
            Expression<Func<T, bool>> second)
        {
            return first.Compose(second, System.Linq.Expressions.Expression.OrElse);
        }
    }
}

使用:

        /// <summary>
        /// 获取新闻列表
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public NiunanAPIResult GetList([FromQuery] NiunanNewsSearchInput model)
        {
            try
            {
                var express = PredicateBuilder.True<NiunanNews>();
                if (model.userid > 0) {
                   express =  express.And(a => a.UserId == model.userid);
                } 
                var list = _niunannewsServices.QueryPage(express, "id desc", model.pageindex, model.pagesize);
                return new NiunanAPIResult() { code = 0, msg = "成功获取新闻列表", data = list };
          
            }
            catch (Exception ex)
            {
                return new NiunanAPIResult() { code = -1, msg = "获取新闻列表出错:" + ex.Message };
            }
        }