简单示例子查询Linq

3

T-SQL查询

Select * from dbo.User_Users
Where UserID IN (Select UserID from Course_Enrollments)

LINQ to Entities替代以上查询
var innerquery = from en in Course_Enrollments
select en.UserID;

var query = from u in User_Users
where innerquery.Contains(u.UserID)
select u;

在stackoverflow上有很多复杂的子查询,我只想看到一个简单的例子,展示如何通过linq完成简单的子查询。这是我的做法,但它不好,因为它向数据库发送了两个查询。


1
你确认了通过分析器发送了2个查询吗?一般情况下,除非对IQueryable进行枚举,或者使用类似于ToList或FirstOrDefault的操作,否则查询不会被实例化。 - ESG
2个回答

6
简单的答案是使用"let"关键字并生成一个支持主实体条件集的子查询。
var usersEnrolledInCourses = from u in User_Users
                                 let ces = from ce in Course_Enrollments
                                           select ce.UserID
                                 where ces.Contains(u.UserID)
                             select u;   

这将在TSQL中创建一个类似于exists块的结构

SELECT [Extent1].*
   FROM dbo.User_Users AS Extent1
   WHERE EXISTS (SELECT 1 AS [C1]
                     FROM dbo.Course_Enrollements AS Extent2
                     WHERE (Extent2.UserID = Extent1.UserId))

这个与您所要求的接近,并且通常在SQL Server上创建相同的查询计划。

希望这能帮到您!


如果有其他性能更好的选项,例如使用连接(join),我不会使用内部子查询。对于Users中的每一行,您将执行一个完整的查询,然后进行包含操作。 - AD.Net

0
from u in User_Users
where u.Course_Enrollments.Any()
select u

如果您已经设置了外键,否则您可以执行此操作

from u in User_Users
join cu in Course_Enrollments on u.UserId equals cu.UserId
select u

你还应该用.Distinct()方法包装其中任何一个


不幸的是,这个答案会导致EF在查询周围包装一个昂贵的distinct。我建议不要在较大的数据集上这样做。 - Greg Grater
@GregGrater,我不确定这个Distinct相对于主查询中每一行的子查询来说会有多昂贵,尤其是在处理更大的数据集时。特别是在Join之后,应该会减少记录数。 - AD.Net

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接