LINQ условное соединение - PullRequest
1 голос
/ 06 марта 2012

Можно ли как-нибудь переписать этот кусок кода, чтобы мне не приходилось дублировать предложения join и where в нескольких запросах?

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

Единственное, что изменяется между двумя запросами, это соединение:

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

с этим соединением:

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

Ответы [ 2 ]

1 голос
/ 06 марта 2012

После хорошего ночного сна я придумал решение, которое очень просто - разделить запрос на 2 части:

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 голосов
/ 06 марта 2012

Это должно сработать, если вы переместили объединение в предложение where, так как оно не использует ни одну из категорий брендов для чего-либо еще.Будет ли это работать?

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 };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...