.net core-将一个func列表与单个func组合在一起

浮点数

您好,我尝试从由或组合而成的列表中生成单个Func。

var funcs = new List<Func<User, bool>>()
{
    (u) => u.Id.Equals(entityToFind.Id),
    (u) => u.UserName == entityToFind.UserName,
    (u) => u.Email == entityToFind.Email
};

//TODO: Some magic that funs is euqaly to that:

Func<User, bool> func =  (u) => u.Id.Equals(entityToFind.Id) || u.UserName == entityToFind.UserName || u.Email == entityToFind.Email;

我也用Expressions尝试过,就像这样:

private Dictionary<string, Expression<Func<User, bool>>>     private Dictionary<string, Expression<Func<User, bool>>> test(User entityToFind)
{
    return new Dictionary<string, Expression<Func<User, bool>>>() {
        {"Id", (u) => u.Id.Equals(entityToFind.Id) },
        {"Name", (u) => u.UserName == entityToFind.UserName },
        {"Email", (u) => u.Email == entityToFind.Email }
    };
}


public static Expression<Func<T, bool>> ToOrExpression<T>(this Dictionary<string, Expression<Func<T, bool>>> dict)
{
    var expressions = dict.Values.ToList();
    if (!expressions.Any())
    {
        return t => true;
    }

    var delegateType = typeof(Func<T, bool>)
        .GetGenericTypeDefinition()
        .MakeGenericType(new[]
            {
                typeof(T),
                typeof(bool)
            }
        );

    var tfd = Expression.OrElse(expressions[0], expressions[1]);

    var combined = expressions
        .Cast<Expression>()
        .Aggregate( (e1, e2) => Expression.OrElse(e1, e2) );

    return (Expression<Func<T, bool>>)Expression.Lambda(delegateType, combined);
}


test(entityToFind).ToOrExpression();

但是我会得到以下错误:

未为类型'System.Func 2[Models.User,System.Boolean]' and 'System.Func2 [Models.User,System.Boolean]'定义二进制运算符OrElse

戴维

尽管您可以创建包装器方法来组合一堆Funcs,因为您使用的是Entity Framework,但这将导致将整个数据集下载到内存中并在本地进行搜索。您应该使用的是Expression<Func<T, bool>>

幸运的是,马克·格雷夫(Marc Gravell已经编写了一些方便的代码来组合表达式您的问题严格是重复的,因为您要将两个以上的组合在一起,但是使用少量的Linq相当容易。因此,让我们先从表达式开始,代码几乎没有变化:

var expressions = new List<Expression<Func<User, bool>>>()
{
    (u) => u.Id.Equals(entityToFind.Id),
    (u) => u.UserName == entityToFind.UserName,
    (u) => u.Email == entityToFind.Email
};

现在使用Marc的代码并将其修改为or而不是and

public static class ExpressionExtensions
{
    public static Expression<Func<T, bool>> OrElse<T>(
        this Expression<Func<T, bool>> expr1,
        Expression<Func<T, bool>> expr2)
    {
        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>>(
            Expression.OrElse(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);
        }
    }
}

不,您可以将表达式与LinqAggregate方法结合使用

var combinedExpression = expressions.Aggregate((x, y) => x.OrElse(y));

并使用像这样的东西:

var result = db.Things.Where(combinedExpression);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

JSON.net将2个列表(JObject)组合在一起

ASP Net Core-将外部身份提供者与单个用户帐户混合在一起以进行审计跟踪

将JWT Bearer身份验证Web API与Asp.Net Core 2.0结合在一起时出现问题

如何使用Lucene.Net将搜索短语与通配符结合在一起?

如何在一个解决方案文件中将Angular 9前端与ASP.NET 4.7 API后端结合在一起?

asp.net:如何将两个模型结合在一起以创建父级及其所有子级实体?

如何将ASP.NET网页站点与MVC 6站点结合在一起

将字典列表与一个公共键组合在一起而不合并值

无法将StencilJS与.net core MVC一起使用

Kotlin通过汇总每个元素将“ N”个列表组合在一起

为什么将 .Net Standard 和 .Net Core 项目混合在一个解决方案中?

未将TestNet .Net Core与TestServer集成在一起,返回404?

将前端与 .NET Core API 组合到一个域中

将SQL查询组合在一起

将数组元素组合在一起

将正确的值组合在一起

将数据聚合/组合在一起

将列表与列表中不同长度的列表组合在一起

如何将列与 Pandas 中的虚拟变量组合在一起(一个输出)?

将一个元素与不同列的所有其他元素组合在一起 / R

在MongoDB中将一个或多个$ match组合在一起

将列表中的元素组合在一起形成新列表

一个将单个结果与多个其他结果结合在一起的数据块

将完整的.NET Framework与现有的ASP.NET Core项目一起使用

为什么将完整的.NET Framework与ASP.NET Core一起使用?

如何将Quartz.NET与ASP.NET Core Web Application一起使用?

将Log4net RemoteSyslogAppender与.Net Core一起使用

将 3 个大表与 2 个连接组合在一起

两个列表整数在python中组合在一起