简体   繁体   English

嵌套的 3 级 LINQ 查询

[英]Nested 3 level LINQ query

Here is my working SQL query I want write LINQ to I have no idea to convert write 3 level nested query这是我的工作SQL查询,我想将LINQ写入我不知道要转换写入 3 级嵌套查询

Select *
from demo.dbo.Account
where accType = 3
and LinkAcc IN (
  select accNum
  from demo.dbo.Account
  here inkAcc IN (
    select accNum
    from demo.dbo.Account
    where memberid = 20
    and accType= 0 
  )
  and accType = 2
) 

When writing LINQ equivalents to a SQL IN() , you have to think about it in reverse.在编写与 SQL IN()等效的 LINQ 时,您必须反过来考虑它。

Rather than the SQL而不是 SQL

where entity-value IN sub-values其中实体值 IN 子值

the LINQ expression becomes LINQ 表达式变为

where sub-values contains entity-value其中子值包含实体值

Because writing this in one monolithic LINQ statement is mind-bending, I have broken each subquery into a separate variable.因为在一个单一的 LINQ 语句中编写它是令人费解的,所以我将每个子查询分解为一个单独的变量。

using System.Linq;

public IEnumerable<Account> FilterAccounts(IEnumerable<Account> accounts)

  // start with the deepest subquery first
  var memberAccountNums = accounts
    .Where(x => x.MemberId == 20 && x.AccType == 0)
    .Select(x => x.AccNum)
    .ToArray();

  var linkAccountNums = accounts
    .Where(x => x.AccType == 2 && memberAccountNums.Contains(x.AccNum))
    .Select(x => x.AccNum)
    .ToArray();

  var result = accounts
    .Where(x => x.AccType == 3 && linkAccountNums.Contains(x.AccNum))
    .ToArray();

  return result;
}

I have used a method here to demonstrate a compilable version of the code (assuming the class and property names are correct).我在这里使用了一个方法来演示代码的可编译版本(假设类和属性名称是正确的)。 You would obviously want to parameterise this to meet your needs.您显然希望对其进行参数化以满足您的需求。

If you want to combine them for some reason (say LINQ-to-SQL), then you could write it as one query, or you could instead use a series of IQueryable variables instead of calling .ToArray() .如果您出于某种原因想要将它们组合起来(比如 LINQ-to-SQL),那么您可以将其编写为一个查询,或者您可以改为使用一系列IQueryable变量而不是调用.ToArray()

I have created a working demo here: https://dotnetfiddle.net/pg0WLC我在这里创建了一个工作演示: https : //dotnetfiddle.net/pg0WLC

I assume that the logic is you want to return all accounts with AccType 3 where there is also a matching AccNum for AccType 0 and 2?我假设逻辑是您想要返回所有 AccType 3 的帐户,其中 AccType 0 和 2 也有匹配的 AccNum? This assumes that the MemberId property will match if the AccNum properties do.这假设如果 AccNum 属性匹配,MemberId 属性将匹配。

Another way of doing this with LINQ would be to use group by:使用 LINQ 执行此操作的另一种方法是使用 group by:

int[] types = new int[] { 0, 2, 3 };

return accounts
  .Where(x => x.MemberId == 20 && types.Contains(x.AccType))          
  .GroupBy(x => x.AccNum)
  .Where(x => x.Count() == types.Count())         
  .SelectMany(x => x)
  .Where(x => x.AccType == 3);

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

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