技术思绪摘录旅行笔记
Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术。帮我们生成标准的SQL和执行数据库操作。

需求来源:界面上要筛选一个列表数据,比如爱好这个字段,数据库存储是多个爱好,逗号隔开,比如:篮球,羽毛球,乒乓球;我现在界面上是一个多选搜索框,可以同时包含多个爱好项目

如下数据:

姓名爱好(hobby)字段
张三篮球,足球
李四篮球,羽毛球
王二羽毛球,棒球

当我界面勾选了棒球和足球的时候,入参如下

{"hobby":["棒球","足球"]}

我应该把张三和王二筛选出来

于是乎,我后台用List<string> model接收到参数

db.table.Where(x=> model.Any(y => x.hobby.Contains(y)) )

EFCore直接告诉我,这个写法无法解释

所以开始自己的封装

        /// <summary>
        ///扩展 ContainsAny
        /// 字段包含数组中的任意一个
        ///  .ContainsAny(model.JobKeyWrods.Count>0, x =>x.KeyWords,model.JobKeyWrods)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="q">The q.</param>
        /// <param name="condition">if set to <c>true</c> [condition].</param>
        /// <param name="text">The text.</param>
        /// <param name="items">The items.</param>
        /// <returns></returns>
        public static IQueryable<T> ContainsAny<T>(this IQueryable<T> q, bool condition, Expression<Func<T, string>> text, List<string> items)
        {
            if (!condition)
            {
                return q;
            }
            Expression<Func<T, bool>> predicate = c => false;
           // var contains = typeof(string).GetMethod("Contains");
            var contains = typeof(string).GetMethod("Contains", new[] { typeof(string) });
            foreach (var item in items)
            {
                var containsExpression = Expression.Call(text.Body, contains, Expression.Constant(item, typeof(string)));
                var lambda = Expression.Lambda<Func<T, bool>>(containsExpression, text.Parameters);
                predicate = predicate.Or(lambda);
            }

            return q.Where(predicate);
        }
        
        // <summary>
        /// Or连接
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expr1">The expr1.</param>
        /// <param name="expr2">The expr2.</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>(Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
        }

这时,改下我们的调用

db.table.ContainsAny(model.Count>0,x.hobby,model)

此时发现,我们的EFCore生成的Sql已经满足我们的要求

select * from table where hobby like '%棒球%' or hobby like '%足球%'


CarsonIT 微信扫码关注公众号 策略、创意、技术

留下您的脚步

 

最近评论

查看更多>>

站点统计

总文章数:275 总分类数:18 总评论数:88 总浏览数:124.81万

精选推荐

阅读排行

友情打赏

请打开您的微信,扫一扫