2010-05-12 7 views
4

만들기 :나는 다음과 같은 쿼리가 동적 LINQ 쿼리

from p in dataContext.Repository<IPerson>() 
    join spp1 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp1.PersonId 
    join s1 in dataContext.Repository<ISports>() on spp1.SportsId equals s1.Id 
    join spp2 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp2.PersonId 
    join s2 in dataContext.Repository<ISports>() on spp2.SportsId equals s2.Id 
    where s1.Name == "Soccer" && s2.Name == "Tennis" 
    select new { p.Id }; 

그것은 축구와 테니스를 재생하는 모든 사람을 선택합니다.
런타임시 사용자는 "Hockey"와 같이 쿼리에 추가 할 다른 태그를 선택할 수 있습니다. 이제 내 질문은 어떻게 동적으로 "Hockey"를 쿼리에 추가 할 수 있을까요? "하키"쿼리에 추가한다면 다음과 같을 것이다 :

from p in dataContext.Repository<IPerson>() 
    join spp1 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp1.PersonId 
    join s1 in dataContext.Repository<ISports>() on spp1.SportsId equals s1.Id 
    join spp2 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp2.PersonId 
    join s2 in dataContext.Repository<ISports>() on spp2.SportsId equals s2.Id 
    join spp3 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp3.PersonId 
    join s3 in dataContext.Repository<ISports>() on spp3.SportsId equals s3.Id 
    where s1.Name == "Soccer" && s2.Name == "Tennis" && s3.Name == "Hockey" 
    select new { p.Id }; 

그것은 바람직 것 쿼리를 구축하는 경우 동적으로 같은 :

private void queryTagBuilder(List<string> tags) 
{ 
    IDataContext dataContext = new LinqToSqlContext(new L2S.DataContext()); 
    foreach(string tag in tags) 
    { 
     //Build the query? 
    } 
} 

누구나하는 방법에 대한 아이디어가있다 이것을 올바르게 설정 했습니까? 미리 감사드립니다.

+0

중복? http://stackoverflow.com/questions/2712337/passing-a-where-clause-for-a-linq-to-sql-query-as-a-parameter/2712795 – Steven

답변

2

나와 내 동료는 해결책을 발견하고는 제대로 작동 할 수 있도록 우리는 쿼리를 리팩토링. 이제 다음 쿼리를 사용하여 올바른 결과 집합을 검색합니다.

var query = dataContext.Repository<ILead>(); 

     foreach (var tag in tags) 
     { 
      String tagName = tag; 
      query = query.Where(l => dataContext.Repository<ISportsPerPerson>() 
         .Any(tpl => tpl.PersonId.Equals(l.Id) && tpl.Sports.Name.Equals(tagName))); 
     } 
// Do something with query resultset :] 
3

LINQ 쿼리는 실제로 실행될 때까지 구문 분석되지 않습니다. 따라서 다음과 같은 작업을 수행 할 수 있습니다.

var q = from r in ctx.records 
     /* Do other stuff */ 
     select r; 

if (!string.IsNullOrEmpty(search)) { 
    q = from r in q 
     where r.title == search 
     select r; 
} 

if (orderByName) { 
    q = q.OrderBy(r => r.name); 
} 

/* etc */ 

이렇게하면 실행중인 하나의 SQL 문이 만들어집니다.

귀하의 특정 질문에 대한 : 조인은 다소 복잡하지만, 나는 다른 "동적"쿼리에 참여할 수 있다고 생각합니다.

그래서 당신은이 같은 끝낼 것 :

var baseQ = from p in dataContext.Repository<IPerson>() 
      select p; 
foreach(var tag in tags) { 
    baseQ = from p in baseQ 
    join spp1 in dataContext.Repository<ISportsPerPerson>() on p.Id equals spp1.PersonId 
    join s1 in dataContext.Repository<ISports>() on spp1.SportsId equals s1.Id 
    where s1.name == tag 
    select p; 
} 

/* If you have defined your relations correct, simplify to something like this. 
    Does not actually work because of SportsPerPerson probably has multiple sports: */ 
foreach(var tag in tags) { 
    baseQ = baseQ.Any(p => p.SportsPerPerson.Sports.Name == tag); 
} 


var resultQ = from p in baseQ 
    select new { p.Id }; 
+0

Looks promesing :] 시도해 볼 것입니다! – Bas

관련 문제