开发者

Passing filtering functions to Where() in LINQ-to-SQL

开发者 https://www.devze.com 2022-12-28 15:41 出处:网络
I\'m trying to write a set of filtering functions that can be chained together to progressively filter a data set. What\'s tricky about this is that I want to be able to define the filters in a differ

I'm trying to write a set of filtering functions that can be chained together to progressively filter a data set. What's tricky about this is that I want to be able to define the filters in a different context from that in which they'll be used. I've gotten as far as being able to pass a very basic function to the Where() clause in a LINQ statement:

filters file:

Func<item, bool> returnTrue = (i) => true;

repository file:

public IQueryable<item> getItems()
{
    return DataContext.Items.Where(returnTrue);
}

This works. However, as soon as I try to use more complicated logic, the trouble begins:

filters file:

Func<item, bool> isAssignedToUser = (i) => i.assignedUserId == userId;

repository file:

public IQueryable<item> getItemsAssignedToUser(int userId)
{
    return DataContext.Items.Where(isAss开发者_如何学JAVAignedToUser);
}

This won't even build because userId isn't in the same scope as isAssignedToUser(). I've also tried declaring a function that takes the userId as a parameter:

Func<item, int, bool> isAssignedToUser = (i, userId) => i.assignedUserId == userId;

The problem with this is that it doesn't fit the function signature that Where() is expecting:

Func<item, bool>

There must be a way to do this, but I'm at a loss for how. I don't feel like I'm explaining this very well, but hopefully you get the gist.

Thanks,

Daniel


You don't need to declare your functions as pure standalone functions. You can use an inline lambda:

public IQueryable<item> getItemsAssignedToUser(int userId)
{
    return DataContext.Items.Where(i => i.assignedUserId == userId);
}

The official documentation for lambdas is here on MSDN, but you might find easier-to-read results searching on Google.


Thanks to the wonders of closures the userId is already in the scope if you use an inline anonymous function in your Where clause. This means that when you have an anonymous function in a method, variables within the method are available to the anonymous function even though they seem to be "outside."

public IQueryable<item> getItemsAssignedToUser(int userId)
{
    return DataContext.Items.Where( i => i.assignedUserId == userId);
}

You also could have created the Func isAssignedToUser inside the method getItemsAssignedToUser and passed it to the Where clause like this, but it would be unnecessary:

public IQueryable<item> getItemsAssignedToUser(int userId)
{
    Func<item, bool> isAssignedToUser = (i) => 
    {
        return i.assignedUserId == userId; 
    };

    return DataContext.Items.Where(isAssignedToUser);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号