C# 如何将 Linq 查询传递给方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/693180/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I pass a Linq query to a method?
提问by Oskar
I'd like to pass a Linq query to a method, how do I specify the argument type?
我想将 Linq 查询传递给方法,如何指定参数类型?
My link query look something like:
我的链接查询看起来像:
var query =
from p in pointList
where p.X < 100
select new {X = p.X, Y = p.Y}
clearly I'm new to Linq, and will probably get rid of the receiving method eventually when I convert the rest of my code, but it seems like something I should know...
显然我是 Linq 的新手,当我转换其余代码时,最终可能会摆脱接收方法,但似乎我应该知道一些事情......
thanks
谢谢
采纳答案by Jon Skeet
You'll need to either use a normal type for the projection, or make the method you're passing it to generic as well (which will mean you can't do as much with it). What exactly are you trying to do? If you need to use the X and Y values from the method, you'll definitely need to create a normal type. (There are horribly hacky ways of avoiding it, but they're not a good idea.)
您需要为投影使用普通类型,或者将您传递给它的方法也设为泛型(这意味着您不能用它做太多事情)。你到底想做什么?如果您需要使用方法中的 X 和 Y 值,您肯定需要创建一个普通类型。(有一些非常糟糕的方法可以避免它,但它们不是一个好主意。)
Note: some other answers are currently talking about IQueryable<T>
, but there's no indication that you're using anything more than LINQ to Objects, in which case it'll be an IEnumerable<T>
instead - but the T
is currently an anonymous type. That's the bit you'll need to work on if you want to use the individual values within each item. If you're notusing LINQ to Objects, please clarify the question and I'll edit this answer.
注意:目前正在讨论其他一些答案IQueryable<T>
,但没有迹象表明您使用的不仅仅是 LINQ to Objects,在这种情况下,它将IEnumerable<T>
改为 - 但T
目前是匿名类型。如果您想在每个项目中使用单独的值,这就是您需要处理的部分。如果您不使用 LINQ to Objects,请澄清问题,我将编辑此答案。
For example, taking your current query (which is slightly broken, as you can't use two projection initializers twice with the same name X). You'd create a new type, e.g. MyPoint
例如,使用您当前的查询(这有点损坏,因为您不能两次使用同名 X 的两个投影初始值设定项)。您将创建一个新类型,例如MyPoint
public sealed class MyPoint
{
private readonly int x;
private readonly int y;
public int X { get { return x; } }
public int Y { get { return y; } }
public MyPoint(int x, int y)
{
this.x = x;
this.y = y;
}
}
Your query would then be:
您的查询将是:
var query =
from p in pointList
where p.X < 100
select new MyPoint(p.X, p.Y);
You'd then write your method as:
然后你将你的方法写为:
public void SomeMethod(IEnumerable<MyPoint> points)
{
...
}
And call it as SomeMethod(query);
并将其称为 SomeMethod(query);
回答by Konstantin Tarkus
public void DoSomething(IQueryable query) { ... }
public void DoSomething<T>(IQueryable<T> query) { ... }
And just in case (if you will need passing expressions):
以防万一(如果您需要传递表达式):
public void DoSomething(Expression exp) { ... }
回答by Adam Robinson
While both tvanfosson and Jon are correct, you can just write your function to accept an IEnumerable<T>
(you can either make your function generic or you can specify the specific concrete generic version you want, which is more likely the correct option) as LINQ to Objects produces an IEnumerable<T>
and LINQ to SQL produces an IQueryable<T>
, which implements IEnumerable<T>
. This option should allow you to be source-agnostic.
虽然 tvanfosson 和 Jon 都是正确的,但您可以编写函数来接受一个IEnumerable<T>
(您可以使您的函数通用,也可以指定您想要的特定具体通用版本,这更有可能是正确的选项),因为 LINQ to Objects 产生anIEnumerable<T>
和 LINQ to SQL 生成一个IQueryable<T>
,它实现了IEnumerable<T>
. 此选项应该允许您与源代码无关。
回答by Daniel
you can also use the below code:
您也可以使用以下代码:
IEnumerable <TableName> result = from x in dataBase.TableName
select x;
methodName(result);
private void methodName (IEnumerable<TableName> result)
{
codes.....
}
回答by William
I think what you are looking for is the Expression class. For instance,
我认为您正在寻找的是 Expression 类。例如,
public void DoSomething()
{
User user = GetUser(x => x.ID == 12);
}
IQueryable<User> UserCollection;
public User GetUser(Expression<Func<User,bool>> expression)
{
return UserCollection.expression;
}