LINQ with ManyToMany: фильтрация на основе множественного выбора - PullRequest
1 голос
/ 23 января 2012

Я новичок в 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 s, которые поддерживают ВСЕ эти функции защиты.

Я уже создал классы LINQ-to-SQLдля моего проекта.Но теперь я застрял, потому что я не знаю, как реализовать фильтрацию.Все команды LINQ, которые я нашел до сих пор, дали бы мне Relay s для одной функции защиты.

Я действительно надеюсь, что один из вас может дать мне подсказку.

Ответы [ 4 ]

0 голосов
/ 07 сентября 2013

Я сделал это в 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;
    }

Надеюсь, это поможет.

0 голосов
/ 23 января 2012
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.

0 голосов
/ 23 января 2012

Будет проще, если вы начнете с 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();

UPDATE: на основании вашего комментария должно работать следующее, однако следите за сгенерированным 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();
0 голосов
/ 23 января 2012
// 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();
}

Это не особенно эффективно, но это должно помочь вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...