Oskar
Oskar

Reputation: 2314

How do I pass a Linq query to a method?

I'd like to pass a Linq query to a method, how do I specify the argument type?

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...

thanks

Upvotes: 14

Views: 28136

Answers (5)

William
William

Reputation: 3395

I think what you are looking for is the Expression class. For instance,

public void DoSomething()
{
    User user = GetUser(x => x.ID == 12);
}

IQueryable<User> UserCollection;

public User GetUser(Expression<Func<User,bool>> expression)
{
    return UserCollection.expression;
}

Upvotes: 4

Daniel
Daniel

Reputation: 3374

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.....
    }

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500525

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.)

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 not using LINQ to Objects, please clarify the question and I'll edit this answer.

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

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);

Upvotes: 23

Konstantin Tarkus
Konstantin Tarkus

Reputation: 38378

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) { ... }

Upvotes: 2

Adam Robinson
Adam Robinson

Reputation: 185643

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.

Upvotes: 2

Related Questions