问题标签 [expression-trees]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
4867 浏览

.net - 从一个重要的 IQueryable 编译 Linq 到 SQL 查询

有没有办法使用 CompiledQuery.Compile 方法来编译与 IQueryable 关联的表达式?目前我有一个 IQueryable,后面有一个非常大的表达式树。IQueryable 是使用几种方法构建的,每种方法都提供组件。例如,两种方法可能会返回 IQueryables,然后将它们连接到第三个中。由于这个原因,我不能在 compile() 方法调用中明确定义整个表达式。

我希望将表达式作为 someIQueryable.Expression 传递给 compile 方法,但是这个表达式不是 compile 方法所需的形式。如果我尝试通过将查询直接放入 compile 方法来解决此问题,例如:

在数据上下文中进行调用表单的地方,我收到一条错误消息,指出“getUsers 未映射为存储过程或用户定义的函数”。同样,我不能只将 getUsers 方法的内容复制到我进行编译调用的位置,因为它又会使用其他方法。

有什么方法可以将从“getUsers”返回的 IQueryable 上的表达式传递给 Compile 方法?

更新 后我尝试使用以下代码将我的意志强加于系统:

foo 最终成为:

{System.Data.Linq.SqlClient.SqlProvider+OneTimeEnumerable`1[Model.Entities.User]}

我没有在 foo 中查看结果的选项,因为没有提供扩展结果并运行查询,我只看到消息“操作可能会破坏运行时”。

我只需要找到一种方法让 sql 字符串只生成一次并在后续请求中用作参数化命令,我可以在数据上下文中使用 GetCommand 方法手动执行此操作,但随后我必须显式设置所有参数并自己进行对象映射,考虑到这个特定查询的复杂性,这是几百行代码。

更新

John Rusk 提供了最有用的信息,所以我授予他在这方面的胜利。但是,需要进行一些额外的调整,并且我在此过程中遇到了其他一些问题,所以我想我会“扩展”答案。首先,“操作可能破坏运行时”错误不是由于表达式的编译,它实际上是由于表达式树中的某些深度转换造成的。在某些地方,我需要调用该.Cast<T>()方法来正式转换项目,即使它们是正确的类型。无需过多详细说明,当几个表达式组合成一棵树并且每个分支都可以返回不同的类型时,这基本上是必需的,它们都是公共类的子类型。

解决了不稳定的问题后,我回到了编译问题。约翰的扩展解决方案几乎就在那里。它在树中查找方法调用表达式,并尝试将它们解析为该方法通常返回的底层表达式。我对表达式的引用不是由方法调用提供的,而是由属性提供的。所以我需要修改执行扩展的表达式访问者以包含这些类型:

这种方法可能并不适用于所有情况,但它应该可以帮助任何发现自己处于同样困境的人。

0 投票
3 回答
9106 浏览

c# - 深入学习 C# 表达式树的最佳资源是什么?

当我第一次输入这个问题时,我这样做是为了找到重复的问题,我确信肯定有人已经问过这个问题了。我的计划是关注那些欺骗链接而不是发布这个问题。但据我所知,这个问题以前没有被问过……它没有出现在“相关问题”列表中。

您找到了哪些最好的资源(文章、书籍、博客文章等)来深入了解 C# 中的表达式树? 我一直对他们的能力感到惊讶,现在我要说,“好吧,足够惊讶。我想现在停下来,获得这些东西的博士学位。” 我正在寻找能够系统地、有条不紊地涵盖这些功能的材料,然后通过详细的示例来说明您可以使用它们做什么。

注意:我不是在谈论 lambda 表达式。我说的是Expression< T > 以及所有与它相关并由此产生的东西。

谢谢。

0 投票
1 回答
2171 浏览

.net - 如何更改表达式中参数的类型?

因为我在我的域中使用 POCOS,我希望我的存储库能够接收我的 POCOS 类型的表达式过滤器并将表达式中的参数更改为我的 LINQ 表的类型,我的字段具有相同的名称我的成员,所以我能够通过分解成员和常量来完成 1 和 2 lambda 条件,如果我添加更多条件,这将导致递归解析二进制表达式。

我就是这样结束的,有没有简单的方法来完成这个

我改变它的方式

0 投票
5 回答
4144 浏览

c# - 执行 IQueryable 查询的一部分并将其余部分推迟到 Linq for Objects

我有一个 Linq 提供程序,它成功地从我选择的数据源中获取数据,但是现在我有了过滤的结果集,我想做的是允许 Linq to Objects 处理表达式树的其余部分(对于诸如联接之类的事情,投影等)

我的想法是,我可以通过 ExpressionVisitor 将包含 IQueryProvider 的表达式常量替换为结果集 IEnumerable,然后返回该新表达式。还从我的 IQueryable 返回 IEnumerable 的提供程序...但这似乎不起作用:-(

有任何想法吗?

编辑:这里有一些很好的答案,但给出的形式......

在我的提供者中,我可以轻松地从客户和订单中取回 2 个结果集,如果数据来自 SQL 源,我只需构造并传递 SQL Join 语法,但在这种情况下,数据不是来自 SQL 源,所以我需要在代码中进行连接...但正如我所说我有 2 个结果集,并且 Linq to Objects 可以进行连接...(以及后来的投影)只需替换表达式常量MyProv.Table<Customer>MyProv.Table<Order>使用List<Customer>andList<Order>并让List<>提供者处理表达式……这可能吗?如何?

0 投票
1 回答
4584 浏览

linq - 打印出 Linq 表达式树层次结构

动态语言运行时 (DLR)有一些非常酷的 表达式代码,包括一些非常好的代码来打印我想要使用的表达式树,以便:

输出:

我在网上找到了一些代码来执行此操作,但发现它仅在表达式不带参数时才有效。

http://incrediblejourneysintotheknown.blogspot.com/2009/02/displaying-nested-evaluation-tree-from.html

然后我发现了类似方法的 DLR 实现。然而,DLR 有自己的 Expression 类和许多其他标准 C# 类型的自定义实现,所以我有点困惑。任何人都知道我可以如何实现上述?

0 投票
4 回答
21092 浏览

c# - 有没有一种简单的方法可以将(lambda 表达式)字符串解析为 Action 委托?

我有一个方法可以根据传递给它的操作委托更改“帐户”对象:

这按预期工作......

...但现在我想做的是有一个这样的方法:

然后可以像这样使用它:

禁用帐户“Account1234”。

我已经查看了linq 动态查询库,它似乎或多或少地做了我想要的,但对于 Func 类型委托,我对表达式树等的了解还不够好,无法弄清楚如何实现我的目标想。

有没有一种简单的方法可以做我想做的事,还是我需要正确学习表达式并编写大量代码?

(我想这样做的原因是允许从用户可以指定 lambda 表达式来执行更改的 powershell 脚本批量更新帐户对象的简单方法。)

0 投票
6 回答
12383 浏览

c# - C# LINQ to SQL:重构此通用 GetByID 方法

我写了以下方法。

基本上,它是通用类中的一个方法,其中T是 DataContext 中的一个类。

该方法从 T ( GetTable) 的类型中获取表,并检查输入参数的第一个属性(始终是 ID)。

这样做的问题是我必须先将元素表转换为列表才能GetType对属性执行 a ,但这不是很方便,因为表的所有元素都必须枚举并转换为 a List

如何重构此方法以避免ToList在整个表上出现 a ?

[更新]

我不能Where直接在桌子上执行的原因是因为我收到了这个异常:

方法 'System.Reflection.PropertyInfo[] GetProperties()' 不支持对 SQL 的转换。

因为GetProperties不能翻译成SQL。

[更新]

有人建议为T使用接口,但问题是T参数将是在[DataContextName].designer.cs中自动生成的类,因此我无法使其实现接口(而且实现LINQ 的所有这些“数据库类”的接口;而且,一旦我将新表添加到 DataContext,文件将重新生成,从而丢失所有写入的数据)。

所以,必须有更好的方法来做到这一点......

[更新]

我现在已经像Neil Williams的建议那样实现了我的代码,但我仍然遇到问题。以下是代码的摘录:

界面:

DataContext [查看代码]:

通用方法:

在这一行抛出return table.SingleOrDefault(e => e.ID.Equals(id));异常:异常是:

System.NotSupportedException: The member 'MusicRepo_DataContext.IHasID.ID' has no supported translation to SQL.

[更新] 解决方法:

Denis Troller发布的答案和Code Rant 博客上的帖子链接的帮助下,我终于设法找到了解决方案:

0 投票
3 回答
1245 浏览

.net - 散列表达式树

我正在将一些伪智能缓存构建到LINQ 查询提供程序中。我想做的(理想情况下)是在某些情况下使用给定查询的表达式树作为缓存键。但是,我不想存储整个对象图本身,那么从表达式树中获取类似哈希和的值的快速方法是什么?或者如果我走错了方向,还有更好的选择吗?

0 投票
8 回答
2946 浏览

c# - 如何将方程转换为单个变量的公式?

如何将方程转换为单个变量的公式?我正在考虑一个数学方程式,例如:

我想要一个可以处理任何公式的函数,并给我单独的变量公式。上述等式将产生以下结果:

我也想从以下开始:

和输出:

我看过表达式树,但我无法想象它是如何工作的。我想要一个 .NET(C#、VB.NET 或 F#)解决方案。有任何想法吗?

就像是:

谢谢。

0 投票
3 回答
9119 浏览

c# - C#:如何将任意字符串解析为表达式树?

在我正在进行的一个项目中,我必须使用一个相当奇怪的数据源。我可以给它一个“查询”,它会返回一个 DataTable。但是查询不是传统的字符串。它更像是......一组定义我想要的标准的方法调用。这些方面的东西:

从本质上讲,它支持所有标准的东西(布尔运算符、括号、一些函数等),但编写它的语法非常冗长且不适合日常使用。

我想制作一个小解析器来解析给定的表达式(如"Column1 = 123 AND Column2 < 456")并将其转换为上述函数调用。另外,如果我可以在那里添加参数会很好,这样我就可以免受注入攻击。顶部的最后一点糖是如果它可以缓存解析结果并在要在另一个对象上重新执行相同的查询时重用它们。

所以我想知道 - 是否有任何现有的解决方案可以用于此,或者我是否必须推出自己的表达式解析器?这并不太复杂,但如果我可以节省两三天的编码时间和大量需要修复的错误,那将是值得的。