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
可以具有多个保护功能,对于每个功能,它都有TimeToSaturate
和Remanence
的特定值。现在我想实现一个过滤器。用户可以通过DataGridView
中的复选框选择保护功能,ListBox
应显示支持所有这些保护功能的所有Relay
。
我已经为我的项目创建了LINQ到SQL类。但现在我被卡住了,因为我不知道如何实现过滤。到目前为止,我发现的所有LINQ命令都会为一个保护功能提供所有Relay
。
我真的希望你们中的一个能给我一个提示。
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;
}
希望能有所帮助。