我不是很精通Lambda,所以在用Lambda编写SQL查询时面临一些挑战。2我用SQL编写查询有两种方法:
SELECT A.*
FROM Table1 A
WHERE A.Col1 IN (
SELECT B.Col1
FROM Table1 B
JOIN Table2 C ON B.Col1 = C.Col1
WHERE B.Col2 = 'Condition'
)
或者
SELECT A.*
FROM Table1 A
,Table1 B
,Table2 C
WHERE A.Col1 = B.Col1
AND B.Col1 = C.Col1
AND B.Col2 = 'Condition'
请有人帮我用lambda在Linq中写这个。提前谢谢。
1条答案
按热度按时间carvr3hs1#
对于此示例:
如果A和B是同一个表(Table 1)的别名,那么这个示例就没有任何意义,而且阅读整个内容看起来就像是试图构建一个简单的真实查询示例,但最终却编写了完全无效的内容。
您的查询基本上可以写成:
Entity Framework不仅仅是一个用Linq Lambda替代SQL的工具。是的,使用EF,您可以在DbSet之间编写带有
Join
表达式的Linq,但99.5%的情况下您永远不需要这样做。相反,您可以配置或者让EF解决表之间的关系(前提是数据库遵循公认的命名和规范化约定),EF负责后台的必要连接。例如,您有一个包含Customers & Orders的系统。一个Customer有许多订单。这些表中的每一个都将声明一个实体,但这些实体之间的关系也将被Map。
在一些例子中,你可能会发现像
[ForeignKey]
或关系配置这样的东西不见了。EF可以根据约定自动地计算出关系,不幸的是,这些关系可能有3到4种不同的配置方式。(注解与EntityTypeConfiguration中或OnModelCreating期间的显式配置相比,或者通过约定),所以不幸的是,示例可能会有点混乱,这取决于您在哪里查看。现在,在SQL中,如果我们需要特定Order Number的订单和客户详细信息,您可以编写如下内容:
如果忽略导航属性,Linq if 将如下所示:
老实说,这是相当难看的。然而,对于导航属性,您不需要使用
Join
,您只需访问或立即加载关联的导航属性。EF在后台计算出所需的SQL JOIN:在这里,我们加载单个Order记录并立即加载其客户的导航属性。现在,当您需要订单的客户详细信息时,只需访问order. Customer。或者,如果我们需要特定的Customer及其Orders:
如果您忘记添加
Include
,并且您的DbContext设置为支持延迟加载,那么只要DbContext仍然可以访问并且没有被释放,导航属性仍然可以工作。访问没有被立即加载的导航属性可能会触发对数据库的回调,以“延迟加载”相关数据。通常应该避免这种情况,因为它可能会导致一些非常严重的性能损失。尤其是在处理实体及其相关数据的集合时。如果延迟加载被禁用,则这可能导致相关数据被保留#null,或者可能不完整/不可靠,因为EF仍将填充它当时可能跟踪的任何相关实体。您还可以更有选择性,这样就可以使用
Select
之类的命令(称为“Projection”)来汇总或选择要提取的数据,而不是加载有关客户和/或订单的所有内容。例如,要获得在给定日期之后拥有订单的客户的摘要,可以列出客户的几个字段、自该日期以来的订单计数和摘要(最多)5个最近的订单。请注意,根本不需要
Include
或Join
语句。EF配置了实体和底层表的相关方式,并将生成SQL,以基于我们构建的Linq表达式获取我们想要的数据。在阅读数据时,我强烈建议理解并使用投影来获取数据,因为这可以大大减少DbContext需要传输和跟踪的数据量,并避免急切加载与懒惰加载的缺陷。