GVKun编程网logo

.NetCore 使用 Linq 动态拼接 Expression 表达式条件来实现 对 EF、EF Core 扩展查询排序操作

27

在本文中,我们将为您详细介绍.NetCore使用Linq动态拼接Expression表达式条件来实现对EF、EFCore扩展查询排序操作的相关知识,此外,我们还会提供一些关于*LeetCode10Re

在本文中,我们将为您详细介绍.NetCore 使用 Linq 动态拼接 Expression 表达式条件来实现 对 EF、EF Core 扩展查询排序操作的相关知识,此外,我们还会提供一些关于*LeetCode 10 Regular Expression Matching 正则表达式、.NET Core 3.0 特性初探:C# 8、WPF、Windows Forms、EF Core、.NET Core 类库使用 EFCore DbContext 作为 Nuget 找不到 EFCore、.NetCore 扩展封装 Expression> 查询条件遇到的问题的有用信息。

本文目录一览:

.NetCore 使用 Linq 动态拼接 Expression 表达式条件来实现 对 EF、EF Core 扩展查询排序操作

.NetCore 使用 Linq 动态拼接 Expression 表达式条件来实现 对 EF、EF Core 扩展查询排序操作

相信在使用 EF 的时候对查询条件或者排序上的处理令人心烦,下面我们就来动态拼接表达式解决这一问题

当我们在查询中使用 Where 的时候可以看到如下参数

下面我们就来扩展 Expression<Func<T,bool>> 这个参数

第一步: 建立处理功能类

首先我们要创建一个查询条件转化为表达式的泛型功能类 如 UosoExpressionParser<T> 至于为什么要用泛型类目的很明确就是为了适配不同的模型参数

转化条件为表达式 那么处理一个方法来接受条件 返回表达式,条件可以按照自己的模式去设置

public Expression<Func<T, bool>> ParserConditions(IEnumerable<UosoConditions> conditions)
        {
            //将条件转化成表达是的Body
            var query = ParseExpressionBody(conditions);
            return Expression.Lambda<Func<T, bool>>(query, parameter);
        }
public class UosoConditions
    {
        /// <summary>
        /// 字段名称
        /// </summary>
        public string Key { get; set; }
        /// <summary>
        ///
        /// </summary>
        public string Value { get; set; }
        /// <summary>
        /// 值类型
        /// </summary>
        public string ValueType { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public UosoOperatorEnum Operator { get; set; }
    }

第二步: 条件转表达式具体处理

具体去实现  ParseExpressionBody 条件 枚举提供操作方式 如:(like 、 = 、!= 、>   、< 、>=  、<=  、in 、 between) 

private Expression ParseExpressionBody(IEnumerable<UosoConditions> conditions)
        {
            if (conditions == null || conditions.Count() == 0)
            {
                return Expression.Constant(true, typeof(bool));
            }
            else if (conditions.Count() == 1)
            {
                return ParseCondition(conditions.First());
            }
            else
            {
                Expression left = ParseCondition(conditions.First());
                Expression right = ParseExpressionBody(conditions.Skip(1));
                return Expression.AndAlso(left, right);
            }
        }
private Expression ParseCondition(UosoConditions condition)
        {
            ParameterExpression p = parameter;
            Expression key = Expression.Property(p, condition.Key);
            Expression value = Expression.Constant(condition.Value);
            switch (condition.Operator)
            {
                case UosoOperatorEnum.Contains:
                    return Expression.Call(key, typeof(string).GetMethod("Contains",new Type[] { typeof(string) }), value);
                case UosoOperatorEnum.Equal:
                    return Expression.Equal(key, Expression.Convert(value, key.Type));
                case UosoOperatorEnum.Greater:
                    return Expression.GreaterThan(key, Expression.Convert(value, key.Type));
                case UosoOperatorEnum.GreaterEqual:
                    return Expression.GreaterThanOrEqual(key, Expression.Convert(value, key.Type));
                case UosoOperatorEnum.Less:
                    return Expression.LessThan(key, Expression.Convert(value, key.Type));
                case UosoOperatorEnum.LessEqual:
                    return Expression.LessThanOrEqual(key, Expression.Convert(value, key.Type));
                case UosoOperatorEnum.NotEqual:
                    return Expression.NotEqual(key, Expression.Convert(value, key.Type));
                case UosoOperatorEnum.In:
                    return ParaseIn(p, condition);
                case UosoOperatorEnum.Between:
                    return ParaseBetween(p, condition);
                default:
                    throw new NotImplementedException("不支持此操作");
            }
        }

这里对 In  和 between 做了特殊处理

private Expression ParaseBetween(ParameterExpression parameter, UosoConditions conditions)
        {
            ParameterExpression p = parameter;
            Expression key = Expression.Property(p, conditions.Key);
            var valueArr = conditions.Value.Split('','');
            if (valueArr.Length != 2)
            {
                throw new NotImplementedException("ParaseBetween参数错误");
            }
            try
            {
                int.Parse(valueArr[0]);
                int.Parse(valueArr[1]);
            }
            catch {
                throw new NotImplementedException("ParaseBetween参数只能为数字");
            }
            Expression expression = Expression.Constant(true, typeof(bool));
            //开始位置
            Expression startvalue = Expression.Constant(int.Parse(valueArr[0]));
            Expression start = Expression.GreaterThanOrEqual(key, Expression.Convert(startvalue, key.Type));

            Expression endvalue = Expression.Constant(int.Parse(valueArr[1]));
            Expression end = Expression.GreaterThanOrEqual(key, Expression.Convert(endvalue, key.Type));
            return Expression.AndAlso(start, end);
        }
private Expression ParaseIn(ParameterExpression parameter, UosoConditions conditions)
        {
            ParameterExpression p = parameter;
            Expression key = Expression.Property(p, conditions.Key);
            var valueArr = conditions.Value.Split('','');
            Expression expression = Expression.Constant(true, typeof(bool));
            foreach (var itemVal in valueArr)
            {
                Expression value = Expression.Constant(itemVal);
                Expression right = Expression.Equal(key, Expression.Convert(value, key.Type));
               
expression = Expression.Or(expression, right); }
return expression; }

第三步: 扩展分页、排序、查询条件

扩展 IQueryable<T> 就 OK 了,下面是我扩展的查询 排序 分页处理

扩展查询

public static IQueryable<T> QueryConditions<T>(this IQueryable<T> query, IEnumerable<UosoConditions> conditions)
        {
            var parser = new UosoExpressionParser<T>();
            var filter = parser.ParserConditions(conditions);
            return query.Where(filter);
        }

扩展多条件排序

public static IQueryable<T> OrderConditions<T>(this IQueryable<T> query, IEnumerable<UosoOrderConditions> orderConditions)
        {
            foreach (var orderinfo in orderConditions)
            {
                var t = typeof(T);
                var propertyInfo = t.GetProperty(orderinfo.Key);
                var parameter = Expression.Parameter(t);
                Expression propertySelector = Expression.Property(parameter, propertyInfo);

                var orderby = Expression.Lambda<Func<T, object>>(propertySelector, parameter);
                if (orderinfo.Order == OrderSequence.DESC)
                    query = query.OrderByDescending(orderby);
                else
                    query = query.OrderBy(orderby);

            }
            return query;
        }

扩展分页

public static IQueryable<T> Pager<T>(this IQueryable<T> query, int pageindex, int pagesize,out int itemCount)
        {
            itemCount = query.Count();
            return query.Skip((pageindex - 1) * pagesize).Take(pagesize);
        }

扩展基本完成了,接下来就是使用方式 下面是我写的查询分页方式

第四步: 具体使用方式

public IList<IdentityUser> GetPagedList2(IEnumerable<UosoConditions>  conditions,IEnumerable<UosoOrderConditions> orderConditions,int pageIndex, int pageSize,out int itemcount)
        {
            return _userManager.Users.AsNoTracking().QueryConditions(conditions).OrderConditions(orderConditions).Pager(pageIndex, pageSize, out itemcount).ToList();
        }

你需要构建相关的查询排序集合类就行了 如下:

List<UosoConditions> uosoConditions = new List<UosoConditions>() {
                 new UosoConditions { Key = "UserName", Operator = UosoOperatorEnum.Contains, Value = "1,3", ValueType = "string" }
            };
            List<UosoOrderConditions> orderConditions = new List<UosoOrderConditions> {
                 new UosoOrderConditions{
                      Key="UserName",
                       Order = OrderSequence.DESC
                 },
                 new UosoOrderConditions{
                      Key="PhoneNumber",
                       Order = OrderSequence.DESC
                 }
            };
            int itemcount = 0;
            var list = _userServices.GetPagedList2(uosoConditions, orderConditions, pageindex, pagesize, out itemcount);

第五步:结合前端分页样式实现整体(之前的有介绍)

ViewBag.Option = new UosoPagerOption()
            {
                ItemCount = itemcount,
                PageSize = pagesize,
                PageIndex = pageindex,
                CountNum = 5,
                Url = Request.Path.Value,
                Query = Request.Query
            };

 

以上是实现分页的全部过程,这里值得注意的是 在 like 查询 Contains 的时候,在.NetCore 中需要如下这样写,不然可能会出现反射多次被实例化的问题

typeof(string).GetMethod("Contains",new Type[] { typeof(string) }) 

 如果是.Net Framework 中 为如下方式 

typeof(string).GetMethod("Contains")

 

*LeetCode 10 Regular Expression Matching 正则表达式

*LeetCode 10 Regular Expression Matching 正则表达式

题目:

https://leetcode.com/problems/regular-expression-matching/


思路:

(1)DFS

(2)自动机


DFS版本写的比较烂,然后很长逻辑混乱,基本就是出bug补上。。。

592ms

const int DEBUG = 0;

class Solution {
public:
    bool match(char a,char b) {
        return (a == b || b == '.');
    }
    bool isMatch(string s,string p) {
       if(dfs(s,p,0))
            return true;
        return false;
    }
    bool check(string p,int pos) {
        if( (p.size()-pos) %2 == 0 ){
            for(int i=1+pos; i<p.size(); i+=2)
                if(p[i] != '*')return false;
            return true;
        }
        return false;
    }

    bool dfs(string s,string p,int pos) {
        if(s.size() == 0) {
            /*if( (pos == p.size()&&p[pos-1]!='*' ||
                 (pos == p.size()-1 && p[pos]=='*'))
               )return true;*/
            if( (pos == p.size()&&p[pos-1]!='*' ||
                 (check(p,pos+1) && p[pos]=='*'))
               )return true;
            //if( (pos == p.size() || (check(p,pos) && p[pos]=='*')) )return true;
            if(check(p,pos))return true;
            if(DEBUG) {
                cout << "s.size() == 0 s=" << s << "  p=" << p << "  pos=" << pos << endl;
            }
            return false;
        }
        if(p.size() <= pos) {
            if(DEBUG) {
                cout << "p.size() <= pos s=" << s << "  p=" << p << "  pos=" << pos << endl;
            }
            return false;
        }
        int ptrs = 0,ptrp = pos;
        while(ptrs < s.size() && ptrp < p.size() ) {
            if( match(s[ptrs],p[ptrp]) ) {
                if(ptrp+2 < p.size() && p[ptrp+1] == '*') {
                    if(dfs(s.substr(ptrs),ptrp+2))return true;
                }
                ptrs ++,ptrp ++;
                continue;
            }
            if(p[ptrp] == '*') {
                if(ptrp >= 1) {
                    if( match(s[ptrs],p[ptrp-1]) ) {
                        return dfs(s.substr(ptrs+1),ptrp) | dfs(s.substr(ptrs),ptrp+1);
                        //   | 1 | 0
                    } else {
                        return dfs(s.substr(ptrs),ptrp+1);
                    }
                } else {
                    return false;
                }
                continue;
            } //else {
            if(ptrp+1 < p.size() && p[ptrp+1] == '*'){
                    //cout << "s=" << s.substr(ptrs) << "  p=" << p << "  " << ptrp+2 << endl;
                return dfs(s.substr(ptrs),ptrp+2);
            }
            else
                return false;
            //}
        }
        if( ptrs >= s.size()  ){
            pos = ptrp;
            //if( (pos == p.size()&&p[pos-1]!='*') || (pos == p.size()-1 && p[pos]=='*') )return true;
            //if( (pos == p.size() || (check(p,pos) && p[pos]=='*')) )return true;

            if( (pos == p.size()&&p[pos-1]!='*' ||
                 (check(p,pos+1) && p[pos]=='*'))
               )return true;
            if(check(p,pos))return true;
            return false;

        }
        //if(ptrp >= p.size())return false;
        return false;
    }
};


正则表达式写法:很优雅,但是时间692ms,应该是因为某些可以用循环,但是这里还是递归了


class Solution {
public:
    bool isMatch(string s,string p) {
        return matchHere(s,p);
    }
    bool matchHere(string s,string p) {
        if(s.size() == 0) {
            return p.size()==0 || p.size()%2==0&&p[1]=='*'&&matchStar('\0',s,p.substr(2));
        }
        if(p.size() >=2 && p[1]=='*' && matchStar(p[0],p.substr(2)))
            return true;
        if(s[0] == p[0] || p[0] == '.') {
            return matchHere(s.substr(1),p.substr(1));
        }
        return false;
    }
    //c* and p has erased c*
    bool matchStar(char c,string s,string p){
        int ptr = -1;
        do {
            ++ptr;
            if(matchHere(s.substr(ptr),p))return true;
        } while( ptr<s.size() && ( s[ptr]==c || c=='.' ) );
        return false;
    }
};


正则表达式的写法参考:

http://hexlee.iteye.com/blog/552361

里面有^和&的处理方法

有空再去练习下怎么DFS写得优雅,比如http://blog.csdn.net/doc_sgl/article/details/12719761

.NET Core 3.0 特性初探:C# 8、WPF、Windows Forms、EF Core

.NET Core 3.0 特性初探:C# 8、WPF、Windows Forms、EF Core

.NET Core 的下一个主要版本最近进入了预览阶段,.NET Core 3.0 将支持使用 Windows Presentation Foundation (WPF)、Windows Forms(WinForms)、Entity Framework (EF)、Blazor、 C# 8 和.NET Standard 2.1 构建桌面应用程序。

.NET Core 的下一个主要版本最近进入了预览阶段,.NET Core 3.0 将支持使用 Windows Presentation Foundation (WPF)、Windows Forms(WinForms)、Entity Framework (EF)、Blazor、 C# 8 和.NETStandard 2.1 构建桌面应用程序。

正如 InfoQ报道的那样,WPF 和 WinForms 最近都在 MIT 许可协议下开源。虽然是.NET Core 3.0 的一部分,但它们目前只能在 Windows 上使用,而且微软似乎也不打算将它们移植到其他平台上,但开源为社区将它们移植到 macOS 和 Linux 上提供了可能。

除了在.NET Core 中增加了对 Windows 桌面应用程序的支持外,新版本还将通过引入Blazor 组件来推进对.NET Core Web 开发的支持。Blazor 是一个开放的基于 Web 标准的实验性框架,它支持创建在浏览器中运行的 UI 组件,包括在 WebAssembly .NET 运行时上运行的移动组件。虽然已经可以使用.NET 进行全栈开发,但 Blazor 还处于Alpha 准备阶段,微软还在努力完善技术问题并评估社区的兴趣。

C# 8.0 是.NET Core 3 的另一个重要组件。它带来了许多在其加入 C# 路线图时 InfoQ 已经报道过的新语言特性,包括可空类型、默认接口方法、异步流、Ranges 和递归模式以及大量的其他特性。

.NET Core 3 还将支持 Entity Framework 的新版本EF Core 3,它将包含对 LINQ 实现的重大更改,以提高生成查询的正确性和效率,并检测低效查询。另外,.NET Core 3 将包含 Entity Framework 6.3,允许开发人员移植依赖于它的现有应用程序。

微软.NET 项目管理负责人 Scott Hunter写道,相对于.NET Framework 框架来说,.NET Core 的一个主要优点是更容易向前发展。这是.NET Core 被打包到应用程序可执行文件中的结果,使得应用程序实际上独立于与操作系统绑定的框架。相反,OS 自带的.NET Framework 必然需要与大量依赖它的现有应用程序保持兼容,这大大减慢了它的发展速度。.NET Core 已经开始推动.NET Standard 的发展就是证明,该标准定义了所有.NET 实现中可用的 API 的基线。事实上,自.NET Core 2.1 以来,.NET Standard 2.1 新增了大约 3000 个 API,这些 API 是.NET Core 开源开发的一部分,其中包括Span、ValueTask等。

Hunter 写道,最后需要注意的是,.NET Core 3 的另一个主要关注点是物联网,它支持在 Raspberry Pi 和 Arduino 设备上使用的 GPIO、PWM、SPI 和 I2C API。

本文只是 .NET Core 3 新特性的简要概述,该版本预计将在 2019 年下半年发布。如果你有兴趣尝试一下,请从微软的网站上下载 .NET Core 3 Preview 1。

原文地址:https://www.infoq.cn/article/LF0M2kU-TIxSM983pb8x


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com


本文分享自微信公众号 - dotNET跨平台(opendotnet)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

.NET Core 类库使用 EFCore DbContext 作为 Nuget 找不到 EFCore

.NET Core 类库使用 EFCore DbContext 作为 Nuget 找不到 EFCore

您应该能够创建自己的 .nuspec,然后将其打包。

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <id>MyPackageId</id>
    <version>$version$</version>
    <title>My Package Title</title>
    <authors>My Company Name</authors>
    <owners>My Company Name</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>A description of our package</description>
    <copyright>Copyright 2021</copyright>
    <dependencies>
      <group targetFramework=".NETStandard2.0"> <!-- Libraries *should* target .NET Standard in most cases -->
        <dependency id="SomeOtherNugetPackageInSameSolutionThatShouldHaveSameVersion" version="$version$" />
        <dependency id="Microsoft.Azure.ServiceBus" version="4.1.1" /> <!-- Specify your external dependencies and their required version here -->
      </group>
    </dependencies>
  </metadata>
  <files>
    <file src="bin\$configuration$\netstandard2.0\MyLibrary.dll" target="lib\netstandard2.0" />
  </files>
</package>

在 Azure DevOps 中构建包时,您应该能够选中一个框以将 $version$ 替换为版本。否则,您可以对其进行硬编码。取决于您的团队如何进行版本控制。

重要的部分是 <dependencies> 部分。

,

通常在使用 Jenkins 或 Azure DevOps 等 DevOps 产品时,当构建服务器和/或构建代理未完全更新或已更新但未完全更新时,您可能会遇到此类问题。

看起来您的管道需要重新配置。

发生这种情况时,请查看数字 -- 特别是版本号。当它们看起来不对劲时,这表明有些事情不对劲。在您的情况下,您说您正在构建 .NET Core 3.1,但正在寻找 EF 5.0.4.0。虽然版本没有必须匹配,但从实际角度来看,它们倾向于匹配。

有趣的是,在我的软件开发职业生涯中,这种情况在我身上发生过很多次。最近,当我们开始支持 .NET Core 3.1 而不是 .NET Core 2.2 时,就发生了这种情况。当构建在您的机器上运行而不在构建服务器上运行时,这一点很快就会变得明显!

基本上,管道的每个部分都需要正确处理以下方面:从源代码管理中提取、从配置存储库(例如 NuGet)中提取、在上下文中构建和发布。

.NetCore 扩展封装 Expression<Func<T, bool>> 查询条件遇到的问题

.NetCore 扩展封装 Expression> 查询条件遇到的问题

前面的文章封装了查询条件 自己去组装条件,但是对 And  Or  这种组合支持很差,但是也不是不能支持,只是要写更多的代码看起来很臃肿

根据 Where(Expression<Func<T, bool>>) 我们直接来处理这个,在处理这个之前其实看了下

Expression这个对象的处理,本生里面是包含了 AndAlso 、 Or 的处理   先来看看这个会遇到什么问题?为什么不行?

比如:

Expression.AndAlso(first,second)

来一段之前的扩展

public static Expression AndExpression(this Expression expression, Expression right)
        {
            return  Expression.AndAlso(expression, right);
           
        }
public static Expression OrExpression(this Expression expression, Expression right)
        {
           return Expression.Or(expression, right);
           
        }
public static Expression<Func<T,bool>> ToFilter<T>(this Expression expression)
        {
            return Expression.Lambda<Func<T, bool>>(expression, Expression.Parameter(typeof(T)));
          
        }

 

本质上没什么不同,最后连接都能拿到相关的表达式

Expression filter= Expression.Constant(true, typeof(bool));
            if (!string.IsNullOrEmpty(username))
            {
                filter = filter.AndExpression(new UosoConditions {
                    Key = "UserName",
                    Operator = UosoOperatorEnum.Contains,
                    Value = username,
                    ValueType = "string"
                }.Parser<IdentityUser>());
            }

按照如上写法多写几个条件,2个查询条件,2个值,感觉没问题, 但是运行到Where的时候报错误 表到时Parameter参数的个数对应不上表达式参数的个数,参数丢失了?

参数的值跟随表达式,在组合的时候需要重新组合参数,如果直接组合表达式,参数不会发生变化所以需要处理下参数问题,对(Expression<Func<T, bool>>) 的扩展就迎刃而解了

正确的处理方式:

public static class ExpressionExtensions
    {
        /// <summary>
        /// 添加And条件
        /// </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.AndAlso<T>(second, Expression.AndAlso);
        }
        /// <summary>
        /// 添加Or条件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="first"></param>
        /// <param name="second"></param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Or<T>(
            this Expression<Func<T, bool>> first,
            Expression<Func<T, bool>> second)
        {
            return first.AndAlso<T>(second, Expression.OrElse);
        }
        /// <summary>
        /// 合并表达式以及参数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expr1"></param>
        /// <param name="expr2"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        private static Expression<Func<T, bool>> AndAlso<T>(
        this Expression<Func<T, bool>> expr1,
        Expression<Func<T, bool>> expr2,
        Func<Expression, Expression, BinaryExpression> func)
        {
            var parameter = Expression.Parameter(typeof(T));

            var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
            var left = leftVisitor.Visit(expr1.Body);

            var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
            var right = rightVisitor.Visit(expr2.Body);

            return Expression.Lambda<Func<T, bool>>(
                func(left, right), parameter);



        }


        private class ReplaceExpressionVisitor
 : ExpressionVisitor
        {
            private readonly Expression _oldValue;
            private readonly Expression _newValue;

            public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
            {
                _oldValue = oldValue;
                _newValue = newValue;
            }

            public override Expression Visit(Expression node)
            {
                if (node == _oldValue)
                    return _newValue;
                return base.Visit(node);
            }
        }
    }

使用方法就简单多了

Expression<Func<IdentityUser, bool>> filter = u => true;

            if (!string.IsNullOrEmpty(username))
            {
                filter = filter.And(c => c.UserName.Contains(username));
            }
            if (!string.IsNullOrEmpty(phone))
            {
                filter = filter.And(c => c.PhoneNumber.Contains(phone));
            }
            if (!string.IsNullOrEmpty(email))
            {
                filter = filter.And(c => c.Email.Contains(email));
            }

这里值得注意的是 一定要重新赋值到 filter ,按理说扩展了Expression<Func<T, bool>> 也返回了 Expression<Func<T, bool>>  好像可以不用重新赋值,然而这里并不是这样

如果我们直接

filter.And(c => c.UserName.Contains(username));

这样添加 会发现之中都是第一个参数的条件 都是 true,这是为什么呢?

Expression<Func<IdentityUser, bool>> filter = u => true;

下面看下这段代码其实给之前出现错误的原因是一样的?

private static Expression<Func<T, bool>> AndAlso<T>(
        this Expression<Func<T, bool>> expr1,
        Expression<Func<T, bool>> expr2,
        Func<Expression, Expression, BinaryExpression> func)
        {
            var parameter = Expression.Parameter(typeof(T));

            var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
            var left = leftVisitor.Visit(expr1.Body);

            var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
            var right = rightVisitor.Visit(expr2.Body);

            return Expression.Lambda<Func<T, bool>>(
                func(left, right), parameter);



        }
var parameter = Expression.Parameter(typeof(T)); 是对 T 类中做的反射,本生合并两个带 T 的应该是没问题的,只是因为

与 Expression<Func<IdentityUser, bool>> filter = u => true; 组合后  

Expression.Lambda<Func<T, bool>>(
                func(left, right), parameter);

一直都是True,导致最后的条件都是返回 True 查询条件就无效了,所以需要重新引用赋值 filter




 

关于.NetCore 使用 Linq 动态拼接 Expression 表达式条件来实现 对 EF、EF Core 扩展查询排序操作的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于*LeetCode 10 Regular Expression Matching 正则表达式、.NET Core 3.0 特性初探:C# 8、WPF、Windows Forms、EF Core、.NET Core 类库使用 EFCore DbContext 作为 Nuget 找不到 EFCore、.NetCore 扩展封装 Expression> 查询条件遇到的问题等相关知识的信息别忘了在本站进行查找喔。

本文标签:

上一篇go modules 学习(go module gopath)

下一篇Codeforces1132A——Regular Bracket Sequence(水题)