Как преобразовать процедуру хранения в linq в nopCommerce С#

Как преобразовать процедуру хранения в linq в nopCommerce С#

Мой запрос процедуры хранения

SELECT p.Id
FROM Product p WITH (NOLOCK)
LEFT JOIN Discount_AppliedToProducts dap WITH (NOLOCK)
    ON p.Id = dap.Product_Id
LEFT JOIN Product_Category_Mapping pcm WITH (NOLOCK)
    ON p.Id = pcm.ProductId
LEFT JOIN Discount_AppliedToCategories dac WITH (NOLOCK)
    ON pcm.CategoryId = dac.Category_Id
        AND dac.Category_Id IN (1 ,2 ,3 ,4 ,5 ,6)
LEFT JOIN Product_Manufacturer_Mapping pmm WITH (NOLOCK)
    ON p.Id = pmm.ProductId
LEFT JOIN Discount_AppliedToManufacturers dam WITH (NOLOCK)
    ON pmm.ManufacturerId = dam.Manufacturer_Id
WHERE dap.Discount_Id IN (3)
    OR dac.Discount_Id IN (3)
    OR dam.Discount_Id IN (3)

Мой линк-запрос

var productlist = (from q in _productRepository.Table
                                       select q).ToList();

var discount_AppliedToProductIds = (from dp in _discountRepository.Table
                                    from p in dp.AppliedToProducts
                                    select p).ToList().DistinctBy(d => d.Id).ToList();

var discount_AppliedToCategorieIds = (from dp in _discountRepository.Table
                                      from c in dp.AppliedToCategories
                                      select c).ToList().DistinctBy(d => d.Id).ToList();

var discount_AppliedToManufacturerIds = (from dp in _discountRepository.Table
                                         from m in dp.AppliedToManufacturers
                                         select m).ToList().DistinctBy(d => d.Id).ToList();

var product_Manufacturer_Mapping = (from dp in productlist
                                    from pm in dp.ProductManufacturers
                                    select pm).ToList().DistinctBy(d => d.Id).ToList();

var product_Category_Mapping = (from dp in productlist
                                from pc in dp.ProductCategories
                                select pc).ToList().DistinctBy(d => d.Id).ToList();

var ss = (from p in productlist
      join dap in discount_AppliedToProductIds on p.Id equals dap.Id
      join pcm in product_Category_Mapping on p.Id equals pcm.ProductId
      //join dac in discount_AppliedToCategorieIds on pcm.CategoryId equals dac.Id
      from dac in discount_AppliedToCategorieIds
      join pmm in product_Manufacturer_Mapping on p.Id equals pmm.ProductId
      join dam in discount_AppliedToManufacturerIds on pmm.ManufacturerId equals dam.Id
      from dapd in dap.AppliedDiscounts
      from pacd in dac.AppliedDiscounts
      from damd in dam.AppliedDiscounts
      where discountIds.Any(d => dapd.Id == d || d == pacd.Id || d == damd.Id)
      // innner join condition
      where categoryIds.Any(d => d == dac.Id) && dac.Id == pcm.CategoryId    
    select p).ToList();

Я написал этот код на С#, но этот код не дает должного результата. Теперь я не знаю, в чем проблема в этом коде. Если я запускаю этот код на сервере sql, я получаю правильный результат, но в коде С# я не получаю правильного результата.


person sangeet    schedule 14.03.2017    source источник


Ответы (1)


Прошло много времени с тех пор, как я написал запрос в LINQ, но я, кажется, припоминаю, что если вы хотите смоделировать ЛЕВОЕ СОЕДИНЕНИЕ, вы должны использовать DefaultIfEmpty(), иначе вы получите ВНУТРЕННЕЕ СОЕДИНЕНИЕ.

Смотрите это, ответ показывает, где применить DefaultIfEmpty:

Linq join query, как использовать defaultifempty

Очевидно, что если вы неправильно смоделируете выражение LEFT JOIN, вы получите результаты только тогда, когда все 3 входа дадут значения.

Я бы также предложил не использовать .ToList() для каждого из ваших исходных запросов, потому что это будет манифестировать данные в память и использовать LINQ to Objects для вашего окончательного запроса. Если вы удалите .ToList(), LINQ создаст один запрос к базе данных для всего процесса.

отметка

person Mark Rabjohn    schedule 22.12.2017