LINQ with ManyToMany:基于多个选择进行过滤

时间:2012-01-23 05:59:14

标签: c# linq filter many-to-many

我是C#的新手,必须将它用于我的硕士论文。目前,我面临着一个对我来说有点复杂的问题。

我已经建立了一个具有多对多关系的数据库,如下所示:

Table Relay:  
- id (PK)  
- Name  
- Input  

Table ProtectionFunction:  
- id (PK)  
- ANSI  
- IEC  
- Description  

Table RelayConfig (junction table)  
- RelayID (PK)  
- ProtFuncID (PK)  
- TimeToSaturate  
- Remanence  

问题是,Relay可以有多个保护功能,每个功能都有TimeToSaturateRemanence的特定值。现在我想实现一个过滤器。用户可以通过DataGridView中的复选框选择保护功能,ListBox应显示支持所有这些保护功能的所有Relay

我已经为我的项目创建了LINQ-to-SQL类。但现在我卡住了,因为我不知道如何实现过滤。到目前为止我找到的所有LINQ命令都会为我提供Relay个保护功能。

我真的希望你们中的一个能给我一个提示。

4 个答案:

答案 0 :(得分:0)

// Build a list of protection function ids from your checkbox list
var protFuncIDs = [1,2,3,4];

using(var dc = new MyDataContext())
{
    var result = dc.Relays.Where(r=>protFuncIDs.Join(r.RelayConfigs, pf=>pf, rc=>rc.ProtFuncID, (pf,rc)=>pf).Count() == protFuncIDs.Length).ToArray();
}

这不是特别有效,但是应该为你做到这一点。

答案 1 :(得分:0)

var ids = new int[]{ ... }; 
// if ids is null or ids.Length == 0 please return null or an empty list, 
//do not go further otherwise you'll get Relays without any function filter

var query = Relays.AsQueryable(); 
foreach (var id in ids)    
{
     var tempId = id;
     query = query.Where(r=>r.RelayConfigs.Any(rc=>rc.ProtFuncID == tempId)); 
}
var items  = query.ToList();

<强>更新 刚刚在PredicateBuilder页面上看到了这一点:

  

循环中的临时变量需要避免外部   变量陷阱,其中为每次迭代捕获相同的变量   foreach循环。

答案 2 :(得分:0)

如果从RelayConfigs开始,它会更容易。这样的事情应该有效:

 var protFuncIds = new[]{1,2,3};
 var query = from rc in db.RelayConfigs
             where protFuncIds.Contains(rc.ProtFuncID)
             select rc.Relay;
 var relays = query.Distinct().ToList();

更新: 根据您的评论,以下内容应该有效,但是要监控生成的SQL ...

IQueryable<Relay> query = db.Relays

foreach (var id in ids)
   query = relays.Where(r => r.RelayConfigs.Select(x => x.ProtFuncId).Contains(id));

var relays = query.ToList();

答案 3 :(得分:0)

我在Lightswitch中完成了这个,这是我的预处理查询:

partial void UnusedContactTypesByContact_PreprocessQuery(int? ContactID, ref IQueryable<ContactType> query)
    {
        query = from contactType in query
                where !contactType.ContactToContactTypes.Any(c => c.Contact.Id == ContactID)
                select contactType;
    }

希望有所帮助。