检测应用于 IQueryable的位置

发布于 2024-12-12 06:49:01 字数 394 浏览 0 评论 0原文

如何检测 IQueryable 是否应用了 where 过滤器?

在此代码中,我需要以编程方式知道 queryFiltered 已应用 wherequery 没有

IQueryable<Customer> query = Context.Customers;
IQueryable<Customer> queryFiltered = Context.Customers
                                            .Where(c=>c.Name.Contains("ABC"));

How can I detect if a IQueryable<T> has a where filter applied?

In this code, I need to know programmatically that queryFiltered has a where applied to it and query doesn't

IQueryable<Customer> query = Context.Customers;
IQueryable<Customer> queryFiltered = Context.Customers
                                            .Where(c=>c.Name.Contains("ABC"));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只是我以为 2024-12-19 06:49:02

如果您使用的是 C# 4.0,则可以使用以下示例代码: 获取所有 ' where' 使用 ExpressionVisitor 进行调用

它基于 ExpressionVisitor。它“访问”IQueryable 的各个元素以查找 Where 部分。看起来很简单。

如果您使用的是 C# = 3.5,则可以使用 MSDN 如何:实现表达式树访问者 加上上一个链接中的 WhereFinder (它们可以工作正确地在一起,刚刚测试)

要使用代码:

var wf = new WhereFinder();
var wheres = wf.GetWhere(query.Expression);

if (wheres.Any())
{
    // There are Where in the query!
}

如果您(正确地)像 Rune FS 一样偏执,则对于 WereFinder.VisitMethodCall,请更改 if至

if (expression.Method.Name == "Where" && expression.Method.DeclaringType.FullName == "System.Linq.Queryable")

If you are using C# 4.0 you can use this sample code: Get all 'where' calls using ExpressionVisitor

It's based on ExpressionVisitor. It "visits" the various elements of a IQueryable<T> to find the Where parts. It seems simple enough.

If you are on C# = 3.5, you can use the ExpressionVisitor sample from MSDN's How to: Implement an Expression Tree Visitor PLUS the WhereFinder from the previous link (they work correctly together, just tested)

To use the code:

var wf = new WhereFinder();
var wheres = wf.GetWhere(query.Expression);

if (wheres.Any())
{
    // There are Where in the query!
}

If you are (correctly) as much paranoid as Rune FS, to the WereFinder.VisitMethodCall, change the if to

if (expression.Method.Name == "Where" && expression.Method.DeclaringType.FullName == "System.Linq.Queryable")
拥醉 2024-12-19 06:49:02

最简单的方法是调用 q.Expression.ToString().Contains(".Where(")。如您所见,query.Expression.ToString().Contains(".Where (") 返回 false,而 queryFiltered.Expression.ToString().Contains(".Where(") 返回 true。

如果将其他表达式算作 ",则可能需要比这更复杂的值过滤”,但是表达式访问者方法也是如此。

我承认这有些古怪,但它看起来确实简单得多。

The simplest way is call q.Expression.ToString().Contains(".Where("). As you can see, query.Expression.ToString().Contains(".Where(") returns false while queryFiltered.Expression.ToString().Contains(".Where(") returns true.

You may need more complexity than that if you count other expressions as "filtering", but that is true with the expression visitor approach too.

There's something rather hacky about this I'll grant you, but it does seem much simpler.

绅士风度i 2024-12-19 06:49:01

您必须解析 表达式 上的表达式 属性 IQueryable 实现。

您必须查询 Queryable当您爬取Expression树时调用Where方法

另请注意,虽然 Queryable.Where 将是检测 where 过滤器的最常见方法,但查询语法允许使用其他实现(取决于名称空间)用于 using 指令);如果您有一些未使用 Queryable.Where 扩展方法的内容,那么您必须显式查找该扩展方法(或使用更通用的过滤 Where 方法接受 IQueryable 并返回 IQueryable 的方法)。

ExpressionVisitor 类(如xanatos 指出)提供了一种非常简单的方法来抓取 表达式 树,我强烈建议使用该方法作为处理表达式 树的基础。

值得注意的是,ExpressionVisitor 类实现需要在类级别存储和公开状态。因此,最好(IMO)创建一次性执行操作的内部类,然后使用一个公共方法来每次创建一个新的 ExpressionVisitor 实例;这将有助于处理变异状态,如果做得正确,也将允许该方法是线程安全的(如果这是您关心的问题)。

You will have to parse the Expression that is returned from the Expression property on the IQueryable<T> implementation.

You'll have to query for the Queryable.Where method being called as you crawl the Expression tree.

Also note that while Queryable.Where is going to be the most common way to detect a where filter, query syntax allows for other implementations to be used (depending on what namespaces are used in the using directives); if you have something that is not using the Queryable.Where extension method then you'll have to look for that explicitly (or use a more generic method of filtering for a Where method that takes an IQueryable<T> and returns an IQueryable<T>).

The ExpressionVisitor class (as pointed out by xanatos) provides a very easy way of crawling the Expression tree, I highly recommend using that approach as a base for processing your Expression tree.

Of note is that ExpressionVisitor class implementations are required to store and expose state on the class level. Because of that, it would be best (IMO) to create internal classes that perform the action one-time and then have a public method which creates a new instance of the ExpressionVisitor every time; this will help with dealing with mutating state, and if done properly, will allow the method to be thread-safe as well (if that is a concern of yours).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文