2011-12-08 4 views
2

엔티티 프레임 워크를 처음 사용하기 때문에이 일을 올바르게 수행 할 지 확신 할 수 없습니다.Linq to 엔티티 many-to-many join

CustomerOrder 
------------ 
ID, StaffID, DeptID, Status, other columns... 

Staff 
------------ 
StaffID, other columns... 

StaffDept 
------------ 
StaffID, DeptID - only 2 fields 

Dept 
------------ 
DeptID, other columns... 

직원 구성원이 여러 부서에 속할 수 있습니다 :

나는 4 개 테이블이있다. StaffDept 테이블은이 다 대 다 관계를 저장하기위한 것입니다.

나는의 조합을 검색해야합니다을하지

  • 모든 고객 주문을
  • "진행 중"의 Status을 가지고와 현재의 직원에 대한 여분의 기록 Status "진행 중"
  • Status이 "진행 중"이고 직원 멤버가 고객 주문과 동일한 부서의 구성원 인 추가 레코드가 있습니다.

예를 들어, 만약 내가 다음과 같은 데이터가 : 현재 사용자들이 고객의 주문 1,2,3를 볼 것입니다 # 1 인 경우

Staff 
----- 
1, Mr X, ... 
2, Mr Y, ... 

Dept 
----- 
1, Sales, ... 
2, Marketing, ... 

StaffDept 
----- 
1, 1 
1, 2 
2, 2 

CustomerOrder 
----- 
1, 1, 1, In Progress, ... 
2, 1, 1, Completed, ... 
3, 2, 2, In Progress, ... 
4, 2, NULL, In Progress, ... 

내가 기대합니다. 사용자 # 2는 2,3,4를 볼 것입니다. 여기

내가 지금까지 가지고있는 코드 : 작동

from co in CustomerOrders 
where co.Status != "In Progress" 
    || co.StaffID == @CurrentStaffID 
    || (co.StaffID != @CurrentStaffID 
     && co.DeptID!= null 
     && Staffs.Where(x => x.StaffID == @CurrentStaffID).FirstOrDefault().Depts.Any(x => x.DeptID== co.DeptID)) 
select new CustomerOrderObject 
{ 
    Description = co.Description, 
    Amount = co.Amount, 
    ... 
} 

하지만, ReSharper에서이 FirstOrDefault() 부분은 런타임에 NULL 예외가 발생합니다 뿌려줍니다. 필자는 Linqpad에서 User # 3 (존재하지 않음)을 테스트했으며 오류가 발생하지 않습니다. 예상했던 레코드 2 만 반환합니다. Resharper는 위의 쿼리를 실행하기 전에 Staffs.Where(x => x.StaffID == 3).FirstOrDefault()을 별도의 쿼리로 가져 오길 원하지만, 느리게 만들 것이라고 생각합니다. 나는이 질의 중 어떤 것이 엔티티에 대해 linq에 익숙하지 않은 것처럼 데이터를 얻는 가장 빠른 방법인지는 모르겠다. linq-to-sql을 사용 해왔다. 어떤 충고도 크게 감사 할 것입니다. - 내가하려고하는 조인의 유형을 정확히 설명하는 방법조차 모르겠습니다.

당신은 단순히 기본 키에 의해 Staff의 멤버를 검색하고, 해당 ID에 의해 정확히 한 직원이있을 것이다 알고 있기 때문에

답변

2

, 당신은 SingleFirstOrDefault를 교체해야합니다.

Staffs.Single(x => x.StaffID == @CurrentStaffID).Depts.Any(x => x.DeptID== co.DeptID)) 

편집 1 :

은 아마 당신이 당신의 쿼리 조금 접을 수

StaffDept.Any(sd => sd.StaffId == @CurrentStaffID && sd.DeptID== co.DeptID) 

편집 2 : 불평 ReSharper에서 고정

Staff.Any(x => x.StaffID == @CurrentStaffID && x.Depts.Any(d => d.DeptID == co.DeptID) 
+0

아니라. 그 이유는 이전에 Linqpad가 "NotSupportedException : Single 및 SingleOrDefault 메서드를 최종 쿼리 작업으로 만 사용할 수 있습니다."라는 오류가 발생합니다. 대신이 인스턴스에서 'FirstOrDefault'메서드를 사용하는 것이 좋습니다. " 이것은 linq에서 엔티티에 가입하는 가장 좋은 방법인가요? – JumpingJezza

+0

@JumpingJezza 'StaffDept'에 대해 곧바로 나오는 두 번째 쿼리 버전이 더 잘 작동하는지 확인하십시오. – dasblinkenlight

+0

그 이상한 일.내 엔티티 데이터 모델에서 데이터베이스를 가져온 곳에서 'StaffDept' 테이블을 잘라내 다 대다 (many-to-many) 조인을 거기에 넣었습니다. 나는 약간의 스마트 한 엔티티 프레임웍을 가지고 있다고 가정한다. – JumpingJezza