2

Need help in converting below SQL nested query to a LINQ query?

select P.ProductId, P.Name, C.Name, I.Image
from Product P 
join ProductImage I on P.ProductId = I.ProductId
join ProductCategory C on P.Category = C.CategoryId
where P.ProductId in (select distinct ProductId
                      from ProductVariantMapping M
                      where M.GUID in (select top 3 V.Guid
                                       from [Order] O 
                                       join Inventory V on V.InventoryId = O.InventoryId
                                       group by O.InventoryId, V.Guid
                                       order by Sum(O.Quantity) desc))

Below is my attempt in converting to LINQ query :

var a = (from product in ekartEntities.Products
         join productImage in ekartEntities.ProductImages
                        on product.ProductId equals productImage.ProductId
         join category in ekartEntities.ProductCategories
                        on product.Category equals category.CategoryId
         where product.ProductId
         select new ProductDTO()
                    {
                            ProductId = product.ProductId,
                            Name = product.Name,
                            Category = category.Name,
                            Image = productImage.Image
                    }).ToList();

what is the equivalent of "IN" when converting to LINQ .

I got the solution for 'IN' clause. But how do I use sum(Quantity) in order by after grouping?

I am new to Entity Framework. Can anyone help me?

4
  • What looks like your linq query, have you try anything? Commented Sep 8, 2018 at 7:49
  • @EmreSavcı I have posted it above. Can't you see? Commented Sep 8, 2018 at 7:50
  • Sorry, I see now. What about your linq? Commented Sep 8, 2018 at 7:52
  • @EmreSavcı Updated my try of the LINQ query. Commented Sep 8, 2018 at 8:02

2 Answers 2

3

In LINQ, you will need to use the "contains()" method to generate the 'IN' You need to put a list in the Contains method. If sends a query, that query will be repeated for completions and this will lead to performance loss.

Sample:

var sampleList = (from order ekartEntities.Order
                  join inventory in ekartEntities.Inventory on order.InventoryId equals inventory.InventoryId
                  select order).toList();

var query = (from product in ekartEntities.Products
                        join productImage in ekartEntities.ProductImages
                        on product.ProductId equals productImage.ProductId
                        join category in ekartEntities.ProductCategories
                        on product.Category equals category.CategoryId
                     where sampleList.Contains(product.ProductId)
                        select new ProductDTO()
                        {
                            ProductId = product.ProductId,
                            Name = product.Name,
                            Category = category.Name,
                            Image = productImage.Image
                        }).ToList();
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you so much for your help. Can you also tell me how do I use orderby Sum(Quantity) after grouping them?
I'm sorry it was late. var x = (from ... group orders by new {InventoryId = order.InventoryId, Guid = order.Guid, Quantity = order.Quantity} into orderGrp orderby order.Key.Quantity select new { bla bla })
I needed sum(Quantity), not orderby just "Quantity". Anyways, I got the solution. Thanks, anyways :)
1

Do not apply ToList() in the first query

I made some test.

Test 1 (with my own data):

    var phIds = new List<string>
    {
        //List of Ids
    };
    using (var db = new ApplicationDbContext())
    {
        var studentsId = db.Relations
            .Where(x => phIds.Contains(x.RelationId))
            .Select(x => x.Id)
            .Distinct(); //IQueryable here
        var studentsQuery = from p in db.Students
            where studentsId.Contains(p.Id)
            select p;

        var students= studentsQuery .ToList();
    }

The generated query looks like :

SELECT 
    [Extent1].[Id] AS [Id], 
    [...]
    FROM [dbo].[Students] AS [Extent1]
    WHERE  EXISTS (SELECT 
        1 AS [C1]
        FROM ( SELECT DISTINCT 
            [Extent2].[StudentId] AS [StudentId]
            FROM [dbo].[Relations] AS [Extent2]
            WHERE ([Extent2].[RelationId] IN (N'ccd31c3d-dfa3-4b40-...', N'd2cb05a2-ece3-4060-...'))
        )  AS [Distinct1]
        WHERE [Distinct1].[StudentId] = [Extent1].[Id]
    )

The query looks exactly like I wanted

However, if you add the ToList() in the first query to get the ids, you no longer have an IQueryable but a list.

Test 2 : wrong (I added ToList):

var phIds = new List<string>
{
    //List of Ids
};
using (var db = new ApplicationDbContext())
{
    var studentsId = db.Relations
        .Where(x => phIds.Contains(x.RelationId))
        .Select(x => x.Id)
        .Distinct().ToList(); // No longer IQueryable but a list of 3000 int
    var studentsQuery = from p in db.Students
        where studentsId .Contains(p.Id)
        select p;

    var students= studentsQuery .ToList();
}

The generated query is ugly:

SELECT 
    [Extent1].[Id] AS [Id], 
    [...]
    FROM [dbo].[Patients] AS [Extent1]
    WHERE [Extent1].[Id] IN (611661, 611662, 611663, 611664,.... 
    //more than 3000 ids here
    )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.