相关疑难解决方法(0)

使用LINQ ExpressionVisitor将基本参数替换为lambda表达式中的属性引用

我正在为我们系统的一部分编写数据层,该数据层记录有关每天运行的自动作业的信息 - 作业名称,运行时间,结果,等等.

我正在使用Entity Framework与数据库交谈,但我试图将这些细节隐藏在更高级别的模块之外,我不希望实体对象本身被暴露.

但是,我想使我的界面在用于查找作业信息的标准中非常灵活.例如,用户界面应允许用户执行复杂的查询,例如"给我所有名为'hello'的作业,该作业在上午10:00到11:00之间运行失败." 显然,这看起来像是动态构建Expression树的工作.

所以我希望我的数据层(存储库)能够接受类型Expression<Func<string, DateTime, ResultCode, long, bool>>(lambda表达式)的LINQ表达式,然后在后台将该lambda转换为我的实体框架ObjectContext可以用作Where()子句中的过滤器的表达式.

简而言之,我正在尝试将类型的lambda表达式转换Expression<Func<string, DateTime, ResultCode, long, bool>>Expression<Func<svc_JobAudit, bool>>,其中svc_JobAuditEntity Framework数据对象对应于存储作业信息的表.(第一个委托中的四个参数分别对应于作业名称,运行时间,结果以及分别在MS中花费的时间)

我在使用该ExpressionVisitor课程时取得了很好的进展,直到我碰到了一堵砖墙并收到了一条InvalidOperationException错误消息:

从"VisitLambda"调用时,重写"System.Linq.Expressions.ParameterExpression"类型的节点必须返回相同类型的非null值.或者,覆盖"VisitLambda"并将其更改为不访问此类型的子项.

我完全不知所措.为什么它不允许我将引用参数的表达式节点转换为引用属性的节点?还有另一种方法可以解决这个问题吗?

以下是一些示例代码:

namespace ExpressionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Expression<Func<string, DateTime, ResultCode, long, bool>> expression = (myString, myDateTime, myResultCode, myTimeSpan) => myResultCode == ResultCode.Failed && myString == "hello";
            var result = ConvertExpression(expression);
        }

        private static Expression<Func<svc_JobAudit, bool>> …
Run Code Online (Sandbox Code Playgroud)

c# linq lambda expression visitor

13
推荐指数
2
解决办法
1万
查看次数

通过输入参数来减少表达式

如果我有一个函数委托的表达式,它接受许多参数,如下所示:

Expression<Func<int, int, int, bool>> test = (num1, num2, num3) => num1 + num2 == num3;
Run Code Online (Sandbox Code Playgroud)

是否有一种方式/如何替换其中一个值(比如5 num1)并获得等效表达式:

Expression<Func<int, int, bool>> test = (num2, num3) => 5 + num2 == num3;
Run Code Online (Sandbox Code Playgroud)

编辑:

还需要解决复杂类型,例如:

    Expression<Func<Thing, int, int>> test = (thing, num2) => thing.AnIntProp + num2;
Run Code Online (Sandbox Code Playgroud)

.net c# lambda delegates

8
推荐指数
1
解决办法
1096
查看次数

替换lambda表达式中的参数类型

我试图将lambda表达式中的参数类型从一种类型替换为另一种类型.

我在stackoverflow上找到了其他答案,即这个,但我没有运气.

想象一下你有一个域对象和一个存储库,你可以从中检索域对象.

但是,存储库必须处理自己的数据传输对象,然后映射并返回域对象:

ColourDto.cs

public class DtoColour {

    public DtoColour(string name)
    {
        Name = name;
    }

    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

DomainColour.cs

public class DomainColour {

    public DomainColour(string name)
    {
        Name = name;
    }

    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Repository.cs

public class ColourRepository {
    ...
    public IEnumerable<DomainColour> GetWhere(Expression<Func<DomainColour, bool>> predicate)
    {
        // Context.Colours is of type ColourDto
        return Context.Colours.Where(predicate).Map().ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这将不起作用,因为谓词是针对域模型的,而存储库中的Collection是数据传输对象的集合.

我试图使用an ExpressionVisitor来做到这一点,但无法弄清楚如何只更改ParameterExpression没有例外被抛出的类型,例如:

测试场景

public class ColourRepository …
Run Code Online (Sandbox Code Playgroud)

c# lambda expressionvisitor

7
推荐指数
1
解决办法
2110
查看次数

C# 中的柯里化表达式

我正在尝试构建一个表达式树,我可以将它输入到 Linq2SQL 中,以便它生成一个漂亮的干净查询。我的目的是构建一个过滤器,将任意一组单词与 AND 和 NOT(或 OR 和 NOT)放在一起。因为我想改变我搜索的字段,所以我最好Expresssion<Func<T, string, bool>>通过调用各种辅助函数来组合一个's列表(其中 T 是我正在操作的实体)。然后我会收到一组单词并循环遍历它们并构建一个Expresssion<Func<T, bool>>up(在必要时否定某些表达式),我最终可以将其提供给 .Where 语句。

我一直在使用 LINQKit PredicateBuilder但这段代码处理单参数表达式。然而,它为我自己的尝试提供了一些基础。我的目标是做这样的事情:

var e = (Expression<Func<Entity, string, bool>>)((p, w) => p.SomeField.ToLower().Contains(w));

var words = new []{"amanda", "bob"};

var expr = (Expression<Func<Entity, bool>>)(p => false);
// building up an OR query
foreach(var w in words) {
    var w1 = w;
>>>>expr = Expression.Lambda<Func<Entity, bool>>(Expression.OrElse(expr.Body, (Expression<Func<Entity, bool>>)(p => e(p, w))));
}

var filteredEntities = table.Where(expr);
Run Code Online (Sandbox Code Playgroud)

但是由于我使用的是表达式,所以用 >>>> 标记的行显然是非法的(不能e(p, w) …

c# t-sql linq currying expression-trees

6
推荐指数
1
解决办法
1846
查看次数

将Expression &lt;Func &lt;FromType &gt;&gt;转换为Expression &lt;Func &lt;ToType &gt;&gt;

如何制作通用的辅助方法,以将Func使用的类型从表达式中的一种类型转换为另一种类型

我有一个Expression<Func<IEmployee, bool>>,我想将其转换为

Expression<Func<Employee, bool>>.
Run Code Online (Sandbox Code Playgroud)

第二个类型始终实现第一个类型。一个通用的解决方案是我要实现的目标。

编辑

我已对问题进行了更清晰的编辑。

.net linq expression-trees

2
推荐指数
1
解决办法
1183
查看次数