将带计数的嵌套SQL转换为linQ

时间:2019-01-20 09:10:46

标签: c# sql sql-server linq

我有一个雇员表,其中包含雇员列表。每个员工都有一个ID,一个公司ID,COR_N_ID和一个母亲MOTHER。 MOTHER字段实际上是另一位员工的ID。有些员工还附有另一名Employee,在这种情况下, “母亲”字段已填写。否则,将其保留为空。 员工可以附加一个员工列表,有些则没有。

我有一个SQL请求来获取没有附属员工的员工列表:

select *
from Employee a
where COR_N_ID = 99
and (select count(ID) from Employee b where b.MOTHER = a.ID) = 0;

但是,我一直坚持将其转换为linQ。到目前为止,我所做的事情:

 var query = (from emp in Employee.FindAll(item => ( 
                         item.COR_N_ID == id 
                         ))
                         select new KeyValuePair
                         {
                             Key = business.Id.ToString(),
                             Value = business.CBA_CH_NAME
                         }
            );

请帮忙吗?

我认为我们可以在这里删除COR_N_ID条件。

我只想要一个没有其他员工的所有员工列表。 请注意,将员工链接到另一位员工的字段是MOTHER字段。

我已经尝试过了:

var query = (from emp in Employee.FindAll(item => ( 
                         item.COR_N_ID == id 
                         ))
                         .where(item2 => !Employee.FindAll(item => item.MOTHER == business.ID))

                         select new KeyValuePair
                         {
                             Key = business.Id.ToString(),
                             Value = business.CBA_CH_NAME
                         }
            );

但这不起作用。

我有这个:

before

但是我想要这个:

after

3 个答案:

答案 0 :(得分:0)

摘要

  1. 如果有

  2. 然后运行

    db.Employee
     .Where(level1 => !db.Employee.Any(level2 => level2.MOTHER == level1.ID))
     .ToList();
    
  3. 您得到

Sql到linq

 -----------------------------------------------------------------------------
 |  SQL                                     |   LINQ                         |
 -----------------------------------------------------------------------------
 |  SELECT * From Employee AS A WHERE       |   db.Employee.Where(A =>       |
 -----------------------------------------------------------------------------
 |  (SELECT COUNT(ID) from Employee AS B    |   (db.Employee.Count(B =>      |
 -----------------------------------------------------------------------------
 |  WHERE B.MOTHER = A.ID) = 0              |   B.MOTHER == A.ID))  == 0)    |
 -----------------------------------------------------------------------------

更多方式

db.Employee
.Where(level1 => level1.COR_N_ID == 99)
.Where(level2  => db.Employee.Where(level3=> level3.MOTHER == level2.Id).Count() == 0)

db.Employee
.Where(level1 => level1.COR_N_ID == 99)
.Where(level2  => !db.Employee.Any(level3  => level3.MOTHER == level2.Id))

db.Employee
 .Where(level1 => level1.COR_N_ID == 99 && !db.Employee.Any(level2 => level2.MOTHER == level1.Id))

db.Employee
.Where(level1 => !db.Employee.Any(level2 => level2.MOTHER == level1.Id))

完整代码

using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;

namespace stackoverflow305092
{   
    class Program
    {

        static void Main(string[] args)
        {
            var db = new Model1();
            var emps = db.Employee
            .Where(level1 => !db.Employee.Any(level2 => level2.MOTHER == level1.ID))
                .ToList();
            Console.WriteLine($"ID \t MOTHER \t NAME");

            foreach (var emp in emps)
            {
                Console.WriteLine($"{emp.ID} \t {emp.MOTHER}  \t \t {emp.NAME}");
            }
            Console.ReadLine();
        }
    }

    public class Model1 : DbContext
    {
        public Model1() : base("data source=.;initial catalog=stackoverflow54275000;integrated security=True;") { }
        public virtual DbSet<Employee> Employee { get; set; }
    }


    [Table("Employee")]
    public class Employee
    {
        public int ID { get; set; }
        public int? MOTHER { get; set; }
        public string NAME { get; set; }
    }

    //    CREATE TABLE[dbo].[Employee]
    //    (
    //      [ID][int] NOT NULL,
    //     [MOTHER] [int] NULL,
    //     [NAME] [nvarchar] (250) NOT NULL
    //    )  

}

ref

答案 1 :(得分:0)

下面,我展示了如何使用LINQ的扩展方法(相当于所有代码:))来做与子查询等效的事情:

public static void Main(string[] args)
{
  List<Employee> list = new List<Employee>();

  list = list
    // Here we are using equivalent of a subquery, but in order to include new column,
    // we use Tuple here. You can read about Tuples on Micsorosft pages and this site.
    // You can even name items in Tuple, but I leave it up to you.
    .Select(e => (e.ID, e.MOTHER, e.COR_N_ID, list.Count(innerEmployee => innerEmployee.MOTHER == e.ID)))
    // Now we can use result of our "subquery" in where method.
    .Where(e => e.Item4 == 0 && e.COR_N_ID == 99)
    .ToList();
}

// Sample class for presentation needs :)
public class Employee
{
  public int ID;
  public int MOTHER;
  public int COR_N_ID;
}

答案 2 :(得分:-1)

var res= Employee.FindAll(x=>x.Mother!=id && x.COR_N_ID==99);