0

How to apply Multiple conditions in joins and in operator in linq query. I tried to implement the below code and got strucked. Kindly let me know to implement.

Query:

SELECT now() as "time", COALESCE (sum(inv.total_invoice_amount),0) as value1, loc.location_name as metric FROM location loc 
LEFT JOIN location_user_map LUM ON LUM.location_id = loc.location_id
LEFT OUTER JOIN invoice inv on inv.client_id IN($client_ids) AND inv.location_id = loc.location_id AND $__timeFilter(inv.end_time)
AND inv.status IN (SELECT status_id FROM status WHERE status IN('Paid','Partialy Paid','Open', 'Completed'))
WHERE loc.client_id IN($client_ids) AND loc.location_name NOT IN('Local Purchase') AND loc.location_id != 0 AND LUM.user_id IN($user_ids)
AND inv.is_active = true
GROUP BY loc.location_name
ORDER BY value1 desc

Code:

using (TransactionContext oTransactionContext = new TransactionContext(iClientID, true))
{
    var oPT_Det = (from loc in oTransactionContext.Location
                   join lum in oTransactionContext.LocationUserMap on loc.LocationId equals lum.LocationId

                   join inv in oTransactionContext.Invoice on new { loc.LocationId } equals new { inv.LocationId }
                   select loc);

    return oPT_Det;

}
James Z
  • 12,209
  • 10
  • 24
  • 44
user2432361
  • 133
  • 1
  • 3
  • 9
  • 2
    Does this answer your question? [LINQ Join with "IN" Condition in "On" Clause](https://stackoverflow.com/questions/71495439/linq-join-with-in-condition-in-on-clause) – Svyatoslav Danyliv Mar 25 '22 at 19:41
  • 2
    $client_ids looks like an sql injection hack waiting to happen.. – Caius Jard Mar 25 '22 at 20:53
  • There's no point using left join user maps if you then go and say `where usermaps.something in...` - mentioning any left joined table in a where without "or leftjoinedtable.thing is null" will convert the left join to an inner join – Caius Jard Mar 26 '22 at 05:38

1 Answers1

0

It's not supposed to be this hard, by the way; part of the magic of EF is that it knows how your entities link together and it will do the joins for you. The idea is to use it in the necessary ways for it to write the SQL for you, rather than bring your SQL into C#, jiggle the order and syntax a bit:

var statusIds = context.Statuses
    .Where(s => new[]{"Paid","Partialy Paid","Open", "Completed"}.Contains(s.Status))
    .Select(s => s.StatusId)
    .ToArray();


context.Locations
  .Where(l =>
    clientIdsArray.Contains(l.ClientId) && 
    l.Name != "Local Purchase" &&
    l.LocationId != 0 &&            
    userIdsArray.Contains(l.LocationUserMap)
  )
  .Select(l => new {
    l.LocationId,
    l.Invoices.Where(i => 
        clientIdsArray.Contains(i.ClientId) &&
        statusIds.Contains(I.StatusId)
    ).Sum(i.TotalInvoiceAmount)
  });

Or, perhaps you would start from Invoices instead of locations. It can be easier to start from a many end because the navigation to a one-end is a single property rather than a collection:

context.Invoices.Where(i => 
  i.LocationId != 0 &&
  i.Location.Name != "Local Purchse" &&
  clientIdsArray.Contains(i.Location.ClientId) &&
  statusIds.Contains(i.StatusId) &&
  i.Location.UserMaps.Any(um => userMapIds.Contains(um.UserId))
)
.GroupBy(i => i.Location.Name)
.Select(g => new { Name = g.Key, Tot = g.Sum(i => i.TotalInvoiceAmount))

EF strives to allow you to just manipulate the entity graph as though it were a local thing, and it manages the DB side for you. Sure, sometimes you have to structure things in a certain way to get the results you want or to get it to craft an SQL in a particular way but..

Note that I don't guarantee these queries as written here solve your problem, or even work/compile; there's a relative lack of info on your question and I've made some assumptions (declared) about your relationships. The purpose of this answer is to point out that you can/are supposed to "leave the SQL at the door" when you come into using EF, rather than thinking of everything in SQL terms still and bending your C# approach to SQL ways. It's intended to be rare that we write the word "join" when working with EF

Caius Jard
  • 72,509
  • 5
  • 49
  • 80