Search code examples
c#.netentity-frameworkt-sqlado

Entity Framework equivalent of the following query?


Can someone tell me how to write an EF query that equals to this:

SELECT OI.orderid, 
       OI.inventoryid, 
       VP.vendorid 
FROM   orders O 
       INNER JOIN orderitems OI 
               ON O.orderid = OI.orderid 
       INNER JOIN vendorparts VP 
               ON VP.inventoryid = OI.inventoryid 
WHERE  (SELECT Count(*) 
        FROM   vendorparts 
               INNER JOIN vendors 
                       ON vendorparts.vendorid = vendors.vendorid 
                          AND vendors.candropship = 1 
        WHERE  vendorparts.inventoryid = VP.inventoryid 
               AND vendorparts.vendorid IN ( 1, 17 )) > 1 

I'm trying to do something like this...

var q = from o in _context.Orders
            join oi in _context.Orderitems on o.Orderid equals oi.Orderid
            join vp in _context.Vendorparts on oi.Inventoryid equals  vp.Inventoryid
                where (from vp2 in _context.Vendorparts
                       where vp2.Inventoryid == vp.Inventoryid                           
                       select count(*)) > 1

but obviously that is syntatctically not allowed.


Solution

  • Long answer:

    var vendorIds = new int[] { 1, 17 };
    
    _context
        .Orders
        .Join(_context.Orderitems,
            o => o.Orderid,
            oi => oi.Orderid,
            (o, oi) => new { o, oi })
        .Join(_context.Vendorparts,
            o_oi => o_oi.oi.Inventoryid,
            vp => vp.Inventoryid,
            (o_oi, vp) => new { o_oi.o, o_oi.oi, vp })
        .Where(o_oi_vp => _context.Vendorparts
            .Where(vp
                => vp.Inventoryid == o_oi_vp.vp.Inventoryid
                && vendorIds.Contains(vp.Vendorid))
            .Join(_context.Vendors.Where(v => v.Candropship),
                vp => vp.Vendorid,        
                v => v.Vendorid,
                (vp, v) => new { vp, v })
            .Any())
        .Select(o_oi_vp => new {
            o_oi_vp.oi.orderid, 
            o_oi_vp.oi.inventoryid, 
            o_oi_vp.vp.vendorid 
        });
    

    Short answer: use a stored procedure.