繁体   English   中英

将 SQL 查询转换为 LINQ 方法语法

[英]Convert SQL query to LINQ method syntax

有人可以帮我将以下 SQL 查询翻译成 LINQ 格式→方法语法吗?

select Employees.Id,Positions.Name from Employees 
left join Contracts on Employees.Contract_id=Contracts.Id
left join Positions on Contracts.Position_Id=Positions.Id

当人们来自 SQL 并从 LINQ 和 EF 开始时,我认为人们可能无法欣赏的一件事就是 EF 在幕后为他们做了多少。 他们从 SQL 的角度知道他们知道什么,第一个想法是“我需要一个连接 b 连接 c,所以我需要使用 linq,然后他们可能会用 C#9D5DB62CZ 的语法编写一些东西,然后他们可能会用 C#9D5DB62CZ 写一些东西是如何工作的”将其转换为方法语法(并不总是一个好主意;linq 中的一些东西比查询语法更简洁)

不过,没有必要如此深入地参与 EF。 如果您设置了客户端实体,则它们之间存在导航属性:

//employee has a contract has a position
//positions has contracts has employees

public class Employee{
  public int Id{get;set;}
  public Contract Contract {get;set;}
}
public class Contract{
  public int Id{get;set;}
  public Position Position {get;set;}
  public ICollection<Employee> Employees {get;set;}
}
public class Position{
  public int Id{get;set;}
  public string Name {get;set;}
  public ICollection<Contract> Contracts {get;set;}
}

然后 EF 知道实体和表是如何关联的,所以简单地说就足够了:

context.Employees.Select(r => new { e.Id, e.Contract.Position.Name } );

EF 将执行所有必要的连接来获取请求的数据。 您不需要像 SQL 那样对它进行每次连接。 它是一个“对象/关系映射器”——它的工作是了解这里的一组对象,它们看起来像一个双向链接的树,您可以在其中使用. 成员访问运算符.. 和一组维护树中数据的表。 它将观察您导航树并形成 SQL 以提供结果数据

它不是完美的或通用的,但它非常好并且知道一些巧妙的技巧(如果你说contracts.Select(c => new { c, c.Employees.OrderByDescending(e => e.HireDate).First() })例如,它会将其编写为ROW_NUMBER() OVER(PARTITION BY employeeid ORDER BY hiredate DESC)..WHERE rn = 1 ) 所以对于在其能力范围内的最常见的东西,你可以留在 C# 土地和让它继续翻译。 如果您已达到其限制,您会很快发现(它会抛出任何无法翻译的异常)


脚注:

我一直想知道,在表之间设置了键等为什么永远不能只写一个 SQL 之类的

SELECT e.Id, e.Contracts.Positions.Name
FROM e
WHERE ...

并自动沿着“朝向 1 端”方向的关系移动。 为什么它总是必须如此手动? 为什么很少使用像 NATURAL JOIN 这样几乎没用的鲤鱼,并且在具有 PK:FK 关系的两个列上没有任何东西可以加入? 但是,当您阅读DBA必须说的内容时,会更清楚编码人员和 DBA 对事物的看法略有不同,并且更容易理解为什么他们(和数据库开发人员)可能想要保持他们非常具体的固定方式,以及为什么将它们抽象为提供自动加入是编码人员会在不同级别上做的事情

var data =
    from e in db.Employees
    join c in db.Contracts on e.Contract_id equals c.Contract_id
    join p in db.Positions on e.Position_Id equals p.Position_Id
    select new { Id = e.Id, Name = p.Name };

暂无
暂无

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

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