2014-04-22 3 views
0

이 쿼리가 있습니다. fromdate 및 until은 매개 변수입니다.매개 변수에 따라 조건을 변경할 수 있습니까

List<TimeEntryReportModel> result = (
      from u in ctx.TT_Users 
      join pm in ctx.TT_ProjectMembers on u.UserID equals pm.UserID 
      join e in ctx.TT_EntryLogs on pm.UserID equals e.UserID 
      join p in ctx.TT_Projects on e.ProjectID equals p.ProjectID 
      where e.EntryDate >= fromdate && e.EntryDate <= until.Value && pm.TT_EntryLogs.Sum(q => q.Duration) > 0 
      select new TimeEntryReportModel 
      { 
       UserId = e.UserID, 
       DisplayName = u.DisplayName, 
       UnitId = u.TT_BusinessUnits.UnitId, 
       //select many more property's here that I get from e, p, pm, u etc. 
      } 
    ).Distinct().OrderBy(n => n.DisplayName).ToList(); 

내 컨트롤러 메서드 중 3 가지에서이 결과의 일부 개체에 액세스하려고합니다. 예를 들면 : 한 가지 방법으로 사용자 아이디가 특정 값인 TimeEntryReportModel 객체를 모두 갖고 싶습니다.

return result.Where(e => e.UserId == userId).ToList(); 

또 다른 방법은 다음과 같습니다 :

그래서 방법은 (userId를 메서드의 매개 변수 임)과 같습니다

return result.Where(l => l.UnitId == unitId).ToList(); 

이에게 꽤 많은 작품,하지만 결과 때문에 약 420 개의 TimeEntryReportModels를 포함하고 있으며 다른 메소드 안에는 그 결과의 하위 쿼리를 가져와야하는데 실제로 필요한 데이터를 받기까지 약 10 초가 걸립니다.

이 문제를 해결하는 한 가지 방법은 쿼리를 3 번 ​​복사하여 붙여 넣고 각 쿼리에 필요한 where 조건을 추가하는 것입니다. 하지만 기본적으로 하나의 조건만으로이 전체 쿼리를 다시 작성하기 때문에 이것은 명백합니다. ...이 쿼리가 포함 된 메서드에 전달하는 매개 변수를 기반으로 쿼리에 조건을 추가 할 수 있습니까?

tl; dr 매개 변수를 기반으로 LINQ 쿼리에 조건을 추가 할 수 있습니까?

답변

1

변수 result의 생성에 .ToList() 함수를 사용하면 쿼리가 실행됩니다. 결과가 목록 대신 IQueryable<TimeEntryReportModel> 유형의 변수로 간주되면 나중에 컨트롤러 메서드에서 .ToList()을 호출 할 때 요청이 실행됩니다. 그래서 , 당신은 쓸 수 있습니다 : (같거나 다른 기능에서) 나중에

IQueryable<TimeEntryReportModel> result = (
... 
).Distinct().OrderBy(n => n.DisplayName); 

그리고를 추가하여 쿼리를 지정 where 절 :

... 
var specifiedResult = result.Where(e => e.UserId == userId).ToList(); 

이연 실행, 내 생각에, 하나 LINQ의 주요 관심사.

+0

메서드에서 IQueryable 을 반환하면 "폐기 된 개체에 액세스 할 수 없습니다"라는 오류 메시지가 나타납니다. 어떤 생각이 그걸 해결하는 방법이야? – user1534664

+0

분명히 중괄호 밖에서 데이터를 죽이면 (dataClassDataContext ctx = getDb()) 데이터가 삭제되기 때문입니다. 그렇지 않으면 어떻게해야합니까?그것은 ctx를 죽이지 않고 dataClassDataContext ctx = getDb()와 같이 처리 할 때 작동하는 것으로 보입니다. 그러나 변수를 다 처리 한 후에 변수를 정리하는 방법은 무엇입니까? – user1534664

+0

http://stackoverflow.com/questions/3638160/ensuring-idisposable-call-on-objects-created-in-the-controller-and-handed-off-to 이것은 내가 본 해결책 중 하나입니다. 이전에는 사용했지만 컨트롤러에서 데이터를 회수하지는 않지만 다른 정적 클래스에서 데이터를 다시 처리 할 수는 없습니다. – user1534664

1

일종의 정렬은 논리 OR을 사용하여 동일한 효과를 얻을 수 있습니다. 예를 들어 날짜 매개 변수가 있고 날짜가 선택적이며 쿼리에서 항상 ID를 확인한다고 가정 해 보겠습니다. 이처럼 어디에서 전화를 구성 할 수 있습니다

from u in ctx.TT_Users 
where u.userId >= 1001 
    && (myDateParam == null || u.RegisteredOn >= myDateParam); 

myDateParam가 지정되면 지정된 날짜 이후에 등록 된 1001보다 큰 ID를 가진 모든 사용자를 반환하는 곳. 분명히, 나의 예는 허구입니다 ... 원리가 도움이 될 수 있습니다. myDateParam을 지정하지 않으면 1001보다 큰 ID를 가진 모든 사용자가 리턴됩니다.

단락 회로는 물론 이것을 가능하게합니다. 또한 불리언 및 목록 등으로이를 수행 할 수 있습니다.

관련 문제