2011-08-10 49 views
4

大图:Linq根据子标准选择父项

我正在处理搜索表单,用户可以选择一个或多个条件来筛选搜索结果。其中一个标准与儿童关系有关。

我想创建一个扩展方法到Iqueryable<Parent>,所以我可以用作我的“链接”的一部分。

方法签名(截至目前)是:

public static IQueryable<Parent> ContainsChild(this IQueryable<Parent> qry, int[] childrenIDs) 

父表和子表:

Parent 
    ParentID 
    Name 
    Description 

Child 
    ParentID (FK) 
    AnotherID (from a lookup table) 

Selection criteria: 
int[] ids = new int[3] {1,2,3}; 

用法是这样的:

var parents = repository.All() //returns Iqueryable<Parent> 
public IQueryable<Parent> Search(Search seach){ 
    if (search.Criteria1 != null){ 
     parents = parents.FilterByFirstCriteria(search.Criteria1); 
    } 
    if (search.ChildrenIDs != null){ //ChildrenIDs is an int[] with values 1,2,3 
     parents = parents.ContainsChild(search.ChildrenIDs) 
    } 
} 

我想弄清楚的是如何创建ContainsChild方法,该方法返回一个IQueryable<Parent>其中父母至少有一个阵列中的AnotherID孩子。

(我试图用EF4来实现这个)

任何帮助完全赞赏。

回答

11

也许这样的:

public static IQueryable<Parent> ContainsChild(this IQueryable<Parent> qry, 
    int[] childrenIDs) 
{ 
    return qry.Where(p => p.Children.Any(c => childrenIDs.Contains(c.AnotherID))); 
} 

编辑

只是为了好玩另一种方式,也应该给予同样的结果:

public static IQueryable<Parent> ContainsChild(this IQueryable<Parent> qry, 
    int[] childrenIDs) 
{ 
    return qry.Where(p => p.Children.Select(c => c.AnotherID) 
            .Intersect(childrenIDs).Any()); 
} 

第一个版本生成的SQL看起来更友好虽然,所以我可能会更喜欢第一个版本。

+0

简单而优雅。谢谢,工作很棒! – nandos

相关问题