2012-03-05 3 views
1

joinwhere 절을 여러 쿼리에 복제 할 필요가 없도록이 코드를 다시 작성할 수있는 방법이 있습니까?LINQ 조건부 합계

if (categoryId > 0) 
{ 
    query = from p in _productRepository.Table 
      from pv in p.ProductVariants.DefaultIfEmpty() 
      from pc in p.ProductCategories.Where(pc => pc.CategoryId == categoryId) 
      join psa in _productSpecificationAttributeRepository.Table on p.Id equals psa.ProductId 
      join sao in _specificationAttributeOptionRepository.Table on psa.SpecificationAttributeOptionId equals sao.Id 
      join sa in _specificationAttributeRepository.Table on sao.SpecificationAttributeId equals sa.Id 
      where p.Published && pv.Published && !p.Deleted && psa.AllowFiltering && 
      (!pv.AvailableStartDateTimeUtc.HasValue || pv.AvailableStartDateTimeUtc.Value < nowUtc) && 
      (!pv.AvailableEndDateTimeUtc.HasValue || pv.AvailableEndDateTimeUtc.Value > nowUtc) 
      select new {sa, sao}; 
} 
else if (brandId > 0) 
{ 
    query = from p in _productRepository.Table 
      from pv in p.ProductVariants.DefaultIfEmpty() 
      from pb in p.ProductBrands.Where(pb => pb.BrandId == brandId) 
      join psa in _productSpecificationAttributeRepository.Table on p.Id equals psa.ProductId 
      join sao in _specificationAttributeOptionRepository.Table on psa.SpecificationAttributeOptionId equals sao.Id 
      join sa in _specificationAttributeRepository.Table on sao.SpecificationAttributeId equals sa.Id 
      where p.Published && pv.Published && !p.Deleted && psa.AllowFiltering && 
      (!pv.AvailableStartDateTimeUtc.HasValue || pv.AvailableStartDateTimeUtc.Value < nowUtc) && 
      (!pv.AvailableEndDateTimeUtc.HasValue || pv.AvailableEndDateTimeUtc.Value > nowUtc) 
      select new {sa, sao}; 
} 

//only distinct attributes (group by ID) 
query = from x in query 
     group x by x.sao.Id into xGroup 
     orderby xGroup.Key 
     select xGroup.FirstOrDefault(); 

2 개 쿼리 사이에 변경 유일한 것은이 조인 :와

from pc in p.ProductCategories.Where(pc => pc.CategoryId == categoryId) 

이 가입 : 당신은이 where 절에 가입 이동 한 경우

from pb in p.ProductBrands.Where(pb => pb.BrandId == brandId) 

답변

1

은 숙면 후 나는 매우 간단 솔루션, 함께했다 -이 개 부분에서 쿼리를 분할 :

if (categoryId > 0) 
{ 
    q1 = from p in _productRepository.Table 
     from pc in p.ProductCategories.Where(pc => pc.CategoryId == categoryId) 
     select p; 
} 
else if (brandId > 0) 
{ 
    q1 = from p in _productRepository.Table 
     from pb in p.ProductBrands.Where(pb => pb.BrandId == brandId) 
     select p; 
} 
var query = from p in q1 
      from pv in p.ProductVariants.DefaultIfEmpty() 
      join psa in _productSpecificationAttributeRepository.Table on p.Id equals psa.ProductId 
      join sao in _specificationAttributeOptionRepository.Table on psa.SpecificationAttributeOptionId equals sao.Id 
      join sa in _specificationAttributeRepository.Table on sao.SpecificationAttributeId equals sa.Id 
      where p.Published && pv.Published && !p.Deleted && psa.AllowFiltering && 
      (!pv.AvailableStartDateTimeUtc.HasValue || pv.AvailableStartDateTimeUtc.Value < nowUtc) && 
      (!pv.AvailableEndDateTimeUtc.HasValue || pv.AvailableEndDateTimeUtc.Value > nowUtc) 
      select new { sa, sao }; 

//only distinct attributes (group by ID) 
query = from x in query 
     group x by x.sao.Id into xGroup 
     orderby xGroup.Key 
     select xGroup.FirstOrDefault(); 
0

그것은 작동합니다 그 이유는 다른 카테고리의 브랜드 카테고리를 사용하지 않는 것으로 보입니다. 이게 효과가 있니?

query = from p in _productRepository.Table 
     from pv in p.ProductVariants.DefaultIfEmpty() 
     join psa in _productSpecificationAttributeRepository.Table on p.Id equals psa.ProductId 
     join sao in _specificationAttributeOptionRepository.Table on psa.SpecificationAttributeOptionId equals sao.Id 
     join sa in _specificationAttributeRepository.Table on sao.SpecificationAttributeId equals sa.Id 
     where 
     ((categoryId > 0 && p.ProductCategories.Any(pc => pc.CategoryId == categoryId)) || 
     (brandId > 0 && p.ProductBrands.Any(pb => pb.BrandId == brandId))) && 
     p.Published && pv.Published && !p.Deleted && psa.AllowFiltering && 
     (!pv.AvailableStartDateTimeUtc.HasValue || pv.AvailableStartDateTimeUtc.Value < nowUtc) && 
     (!pv.AvailableEndDateTimeUtc.HasValue || pv.AvailableEndDateTimeUtc.Value > nowUtc) 
     select new { sa, sao }; 
+0

나는이 라인 때문에 일 것입니다 생각하지 않습니다 'pc에서 p.ProductCategories.Where (pc => pc.CategoryId == categoryId)'는 SQL에서 CROSS JOIN을 생성하지만 응답의 where 절은 SQL에서 생성하지 않습니다. –