2010-04-28 60 views
1

我试图编写一组过滤函数,它们可以链接在一起逐步过滤数据集。这很棘手的一点是我希望能够在不同的环境中定义过滤器,而不是使用它们。据我已经得到并且能够通过一个非常基本的功能给Where()子句在LINQ声明:将过滤函数传递给LINQ-to-SQL中的Where()

过滤器文件:

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

库文件:

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

这工作。然而,当我尝试使用更复杂的逻辑,麻烦的开始:

过滤器文件:

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

库文件:

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

这甚至不会因为建ISN userId的与isAssignedToUser()的范围相同。我也尝试声明一个函数,它的用户id作为参数:

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

这里的问题是,它不适合的函数签名在哪里()期待:

Func<item, bool> 

必须有办法做到这一点,但我不知道如何。我不觉得我很好地解释了这一点,但希望你能得到这个主意。

感谢,

丹尼尔

回答

0

感谢的closures奇迹的用户标识已经在范围如果您在WHERE子句中使用内联匿名函数。这意味着当你在一个方法中有一个匿名函数时,该方法中的变量对匿名函数是可用的,尽管它们似乎是“外部的”。

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

你也可以创建了Func键isAssignedToUser方法getItemsAssignedToUser内,它传递给这样的Where子句,但它是不必要的:

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

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

你不需要来声明作为纯粹的独立功能运行。您可以使用内嵌的λ:

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

的lambda表达式的官方文档是here on MSDN,但你可能会发现更容易阅读的结果在谷歌搜索。