简体   繁体   English

加入 Linq 查询的多个条件

[英]Multiple conditions in joins with Linq query

How to apply Multiple conditions in joins and in operator in linq query.如何在 linq 查询中的连接和运算符中应用多个条件。 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;

}

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. EF 的部分魔力在于它知道您的实体如何链接在一起并且它会为您进行连接。 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:这个想法是以必要的方式使用它来为你编写 SQL,而不是将你的 SQL 变成 C#,稍微调整一下顺序和语法:

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. EF 努力让您像操作本地事物一样操作实体图,并为您管理数据库端。 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..当然,有时你必须以某种方式构建事物以获得你想要的结果,或者让它以特定方式制作 SQL 但是......

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.这个答案的目的是指出,当您开始使用 EF 时,您可以/应该“将 SQL 留在门口”,而不是仍然考虑 SQL 术语中的所有内容,并将您的 C# 方法弯曲为 SQL 方法。 It's intended to be rare that we write the word "join" when working with EF在使用 EF 时,我们很少会写“join”这个词

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM