2012-01-23 2 views
1

저는 C#의 새 생명입니다. 저는 그것을 마스터 학위 논문에 사용해야합니다. 지금은 조금 복잡한 문제에 직면하고 있습니다.ManyToMany가있는 LINQ : 다중 선택을 기반으로 필터링

내가 이런 대다 관계 데이터베이스를 설정 한 : TimeToSaturate에 대한 특정 값을 것은이

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

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

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

가하는 Relay 여러 보호 기능을 가질 수 있고, 각각이 가지고 있으며, Remanence. 이제 저는 필터를 실현하고 싶습니다. 사용자는 DataGridView의 확인란을 통해 보호 기능을 선택할 수 있으며 ListBox은 모든 보호 기능을 모두 지원하는 모든 Relay을 표시해야합니다.

저는 이미 프로젝트에 대한 LINQ-to-SQL 클래스를 만들었습니다. 하지만 지금은 필터링을 실현하는 방법을 모르기 때문에 붙어 있습니다. 지금까지 발견 한 모든 LINQ 명령은 하나의 보호 기능에 대해 모두 Relay을 제공합니다.

여러분 중 한 분이 나에게 힌트를 줄 수 있기를 바랍니다.

+0

각 'Relay' 객체는 현재'Relay' 인스턴스와 관련된 ProtectionFunction 만 포함하는'ProtectionFunction (s) '속성을 가져야하는'RelayConfig (s)'속성을 가져야합니다. 생성 된 객체 모델에서 볼 수있는 것이 아닙니까? –

+0

@ M.Babcock - 'RelayConfig'객체에는 'RelayConfig'가 조인되는 단일 행을 포함하는 'ProtectionFunction'속성이 있습니다. 컬렉션이 아닙니다. – SynXsiS

답변

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 루프의

+0

같은 문제는 여기에 jeroenh – vI3Tz

+0

대답을 내 의견을 봐 미안 해요, 나는이 다시 테스트하고 그것이 ID에서 마지막 ID에 해당하는 보호 기능을 지원하는 모든 릴레이를 선택하는 것 같습니다.따라서 적절한 릴레이를 제공하지 못하는 ID 배열을 사용하면 이전에 언급 한 릴레이가 표시됩니다. – vI3Tz

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

특히 효율적인 것은 아니지만 그 트릭을 수행해야합니다.

+0

와우 정말 빨랐어 요! 고맙습니다. 하지만 불행히도 나는 오류가 있습니다. var protFuncIDs = [1,2,3,4];을 변경해야했습니다. ~ int [] protFuncIDs = {1, 2, 3, 4}; 처음에는 오류가 있었기 때문에 이제 코드를 실행하면 LINQ 명령에서 NotSupportedExeption을 얻습니다. 내가 놓친 게 있니? – vI3Tz

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

업데이트 : Lightswitch에서이 작업을 수행 한

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

글쎄요, 여기서는 보호 기능이 1 또는 2 또는 3 또는 모든 조합의 모든 릴레이가 선택되는 것이 문제라고 생각합니다. 내가 찾고있는 것은 보호 기능 1과 2 및 3을 지원하는 릴레이뿐입니다. – vI3Tz

+0

@ vl3Tz 제 편집 참조 – jeroenh

0

는 귀하의 의견에 따라, 다음은 ... 그러나 생성 된 SQL을 모니터링 할 작동해야하며, 도움이

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; 
    } 

희망 : 여기 내 전처리 쿼리이었다.

관련 문제