gpt4 book ai didi

c# - 如何为 Linq-To-Entities 应用动态过滤器并在服务器端执行它们

转载 作者:行者123 更新时间:2023-11-30 16:27:10 24 4
gpt4 key购买 nike

我想编写一个基本上提供条目列表的类。这些条目可以从数据库中读取,也可以在应用程序生命周期内生成。这个类应该提供一种方法来过滤这个条目。是否有可能以一种只需要一个过滤器用于两个源的方式来实现过滤器?

例如:

interface IFilter
{
bool Filter(ILogEntry entry);
}

对于带有 IEnumerable 的 LINQ,将其用作动态过滤器没有问题。

IEnumerable<IFilter> filters;
IEnumerable<ILogEntry> entries;

foreach(var filter in filters)
entries = entries.Where(p => filter.Filter(p));

但是对于 Linq-To-Sql 有两个问题我无法解决:

  1. 如何将上下文提供的LogEntry转换为ILogEntry?
  2. 如何确保查询将在服务器上执行,而不是在本地执行?

下面的代码实际上会在服务器上执行过滤器,这对我来说似乎有点奇怪。但是,如果我在此查询中使用 IFilter,它将 ILogEntry(由 LogEntry 实现)作为参数,则过滤器将应用于客户端:

entities.Logs
.Select(p => new LogEntry() { Message = p.Message })
.Where(p => p.Message == "132");

有没有办法为 ICollection 和 IQueryable 编写过滤器并确保 IQueryable 的过滤器将在 SQL-Server 上执行?

最佳答案

应用该服务器端的唯一方法是将其组合成表达式树,例如:

interface IFilter {
public Expression<Func<ILogEntry, bool>> GetPredicate();
}
...
IQueryable<ILogEntry> entries = ...
foreach(var filter in filters) {
entries = entries.Where(filter.GetPredicate());
}

这需要如下实现:

public Expression<Func<ILogEntry, bool>> GetPredicate() {
return x => x.SomeField == 25;
}

注意:如果您有内存中的数据链,您可以从 IEnumerable<T> 切换至 IQueryable<T>通过使用 .AsQueryable() ,这允许它在本地使用表达式树。

关于c# - 如何为 Linq-To-Entities 应用动态过滤器并在服务器端执行它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8136142/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com