栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在linq中的两个列表之间建立到实体where子句的链接

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在linq中的两个列表之间建立到实体where子句的链接

我是很新,

Linq
EF

您很不走运,因为“简单的事情”在LINQ to Objects中相对容易,但是在LINQ to Entities中却相当困难(几乎不可能)。

为了以某种方式解决它,您需要手动构建LINQ to Entitiescompatible

expression

首先,您需要一些帮助程序来构建表达谓词。PredicateBuilder是一个流行的选择,但它不会产生EF兼容表情和要求

LinqKit
,并
AsExpandable
在仓库里。因此,我使用以下类似的辅助方法,但会产生最终的兼容表达式:

public static class PredicateUtils{    sealed class Predicate<T>    {        public static readonly expression<Func<T, bool>> True = item => true;        public static readonly expression<Func<T, bool>> False = item => false;    }    public static expression<Func<T, bool>> Null<T>() { return null; }    public static expression<Func<T, bool>> True<T>() { return Predicate<T>.True; }    public static expression<Func<T, bool>> False<T>() { return Predicate<T>.False; }    public static expression<Func<T, bool>> And<T>(this expression<Func<T, bool>> left, expression<Func<T, bool>> right)    {        if (Equals(left, right)) return left;        if (left == null || Equals(left, True<T>())) return right;        if (right == null || Equals(right, True<T>())) return left;        if (Equals(left, False<T>()) || Equals(right, False<T>())) return False<T>();        var body = expression.AndAlso(left.Body, right.Body.Replace(right.Parameters[0], left.Parameters[0]));        return expression.Lambda<Func<T, bool>>(body, left.Parameters);    }    public static expression<Func<T, bool>> Or<T>(this expression<Func<T, bool>> left, expression<Func<T, bool>> right)    {        if (Equals(left, right)) return left;        if (left == null || Equals(left, False<T>())) return right;        if (right == null || Equals(right, False<T>())) return left;        if (Equals(left, True<T>()) || Equals(right, True<T>())) return True<T>();        var body = expression.OrElse(left.Body, right.Body.Replace(right.Parameters[0], left.Parameters[0]));        return expression.Lambda<Func<T, bool>>(body, left.Parameters);    }    static expression Replace(this expression expression, expression source, expression target)    {        return new expressionReplacer { Source = source, Target = target }.Visit(expression);    }    class expressionReplacer : expressionVisitor    {        public expression Source;        public expression Target;        public override expression Visit(expression node)        { return node == Source ? Target : base.Visit(node);        }    }}

其次,在控制器中为这样的单个条件定义一个辅助方法

static expression<Func<Person, bool>> AbilityFilter(int index, int value){    return p => p.AllAbilities.OrderBy(a => a.Id).Skip(index).Take(1).Any(a => a.Value > value);}

最后,构建过滤器并将其传递给

GetAll
方法:

var filter = PredicateUtils.Null<Person>();for (int i = 0; i < AbilitiesInput.Count; i++)    filter = filter.And(AbilityFilter(i, AbilitiesInput[i]));GetAll(filter);

使用的技术绝对不是新手,但我认为没有简单的方法可以解决该特定问题。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/576007.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号