LINQ with ManyToMany:基于多选的筛选

本文关键字:于多选 筛选 with ManyToMany LINQ | 更新日期: 2023-09-27 18:21:11

我是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到SQL类。但现在我被卡住了,因为我不知道如何实现过滤。到目前为止,我发现的所有LINQ命令都会为一个保护功能提供所有Relay

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

LINQ with ManyToMany:基于多选的筛选

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循环的。

如果从RelayConfig开始,会更容易。像这样的东西应该起作用:

 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();
// 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();
}

它不是特别有效,但这应该对你有用。

我已经在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;
    }

希望能有所帮助。