我如何传递谓词Linq to SQL 中的Where() 方法?
我有以下模型:
+--------+
| Folder |
+--------+
| 1
|
| *
+----------+ +---------+
| WorkItem |---------| Project |
+----------+ * 1 +---------+
我需要检索具有当前工作项计数的文件夹列表。
如果我指定了一个项目,那么我只需要每个文件夹中与指定项目关联的工作项的计数。
如果未指定项目,则应返回工作项总数。
我有以下 Linq to SQL 代码:
public interface IWorkItemCriteria {
int? ProjectId { get; }
}
public static IQueryable<Folder> GetFoldersWithItemCounts(IWorkItemCriteria criteria) {
var results = from folder in dataContext.Folders
select new {
Folder = folder,
Count = folder.WorkItems.Count()
};
return(results);
}
问题是 - 我想过滤正在计数的工作项。
这是可行的:
var results = from folder in dataContext.Folders
select new {
Folder = folder,
Count = folder.WorkItems.Where(item => item.ProjectId == criteria.ProjectId).Count()
};
但我无法让它使用任何类型的动态谓词/表达式。我尝试使用的语法是:
var results = from folder in dataContext.Folders
select new {
Folder = folder,
Count = folder.WorkItems.Where(filter).Count()
};
我已经尝试过
Predicate<WorkItem> filter = (item => item.ProjectId == criteria.ProjectId);
,但
Expression<Func<WorkItem, bool>> filter = (item => item.ProjectId == criteria.ProjectId)
两者都不会编译 - 给出 The type argument for method 'System.Linq.Enumerable.Where
我已经尝试过
Func<WorkItem, bool> filter = (item => item.ProjectId == criteria.ProjectId);
构建,但随后失败,并显示“查询运算符‘Where’使用的重载不受支持。”
我需要向 IWorkItemCriteria 接口添加其他属性,因此动态构造可由 Linq to SQL 干净地转换的谓词的能力非常重要。
有什么想法吗?
I have the following model:
+--------+
| Folder |
+--------+
| 1
|
| *
+----------+ +---------+
| WorkItem |---------| Project |
+----------+ * 1 +---------+
I need to retrieve a list of Folders with the current count of WorkItems.
If I have specified a Project, then I only want the count of WorkItems in each Folder that are associated with the specified Project.
If no Project is specified, it should return the total WorkItem count.
I have the following Linq to SQL code:
public interface IWorkItemCriteria {
int? ProjectId { get; }
}
public static IQueryable<Folder> GetFoldersWithItemCounts(IWorkItemCriteria criteria) {
var results = from folder in dataContext.Folders
select new {
Folder = folder,
Count = folder.WorkItems.Count()
};
return(results);
}
The problem is - I want to filter the work items that are being counted.
This works:
var results = from folder in dataContext.Folders
select new {
Folder = folder,
Count = folder.WorkItems.Where(item => item.ProjectId == criteria.ProjectId).Count()
};
but I can't get it to use any kind of dynamic predicate / expression. The syntax I'm trying to use is:
var results = from folder in dataContext.Folders
select new {
Folder = folder,
Count = folder.WorkItems.Where(filter).Count()
};
I've tried
Predicate<WorkItem> filter = (item => item.ProjectId == criteria.ProjectId);
and
Expression<Func<WorkItem, bool>> filter = (item => item.ProjectId == criteria.ProjectId)
neither of which will compile - gives The type arguments for method 'System.Linq.Enumerable.Where<TSource> (System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,bool>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
I've tried
Func<WorkItem, bool> filter = (item => item.ProjectId == criteria.ProjectId);
which builds, but then fails with 'Unsupported overload used for query operator 'Where'.'
I'm going to need to add additional properties to the IWorkItemCriteria interface, so the ability to dynamically construct a predicate that can be cleanly translated by Linq to SQL is pretty important.
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为你的问题是你想从第二个表达式(传递给 results.Where.Select() 的那个)中引用一个表达式(过滤器),并且 LINQ to SQL IQueryable 提供程序不知道如何拉动它的价值。
您要做的就是从头开始编写 Select 表达式,以便内联作为动态过滤器的表达式。我不确定,这对于匿名类型来说可能会特别困难。我刚刚找到以下文章,它似乎很好地解释了这一点: http://www. codeproject.com/KB/linq/rewrite_linq_expressions2.aspx
I think your problem is that you'd like to reference one expression (filter) from within a second expression (the one being passed to results.Where.Select()), and that the LINQ to SQL IQueryable provider doesn't know how to pull in the value of that.
What you're going to have to do is compose the Select expression from scratch in order to inline the expression that's your dynamic filter. This might be extra hard with anonymous types, i'm not sure. I just found the following article, it seems to explain this pretty well: http://www.codeproject.com/KB/linq/rewrite_linq_expressions2.aspx
我从 MSDN 上摘下来的东西:这个想法是你只需将它指向一个现有的函数:
using System;
public class GenericFunc
我确信还有其他方法。我记得做过类似的事情
,但我不确定。不再了,我很确定你需要“新”,希望这有帮助:)
Something I grabbed off of MSDN: the idea is that you just point it to an existing function:
using System;
public class GenericFunc
I'm sure there are also other ways. I remember doing something like
But I'm not sure. anymore, I'm quite sure you need the "new" though, hope this helps :)