简单示例子查询 Linq

Posted

技术标签:

【中文标题】简单示例子查询 Linq【英文标题】:Simple Example Subquery Linq 【发布时间】:2014-10-10 21:02:08 【问题描述】:

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;

*** 上有很多复杂的子查询,我只想看一个简单的例子,说明如何通过 linq 完成一个简单的子查询。我就是这样做的,但它不好,因为它向数据库发送了 2 个查询。

【问题讨论】:

您是否确认通过分析器发送了 2 个查询?通常,在枚举 IQueryable 或使用 ToList 或 FirstOrDefault 之类的东西之前,查询不会具体化。 【参考方案1】:

简单的答案是使用 "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 中创建一个存在块,类似于

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 以提高性能)时,我不会进行内部子查询。对于用户中的每一行,您将执行一个完整的查询,然后包含。【参考方案2】:
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 将 TSQL 包装在查询周围的昂贵的 distinct 中。我建议不要这样做,尤其是在较大的数据集上。 @GregGrater,我不确定这个 Distinct 与主查询中每一行的子查询相比会有多昂贵,特别是对于更大的数据集。特别是在 Join 之后应该减少记录。

以上是关于简单示例子查询 Linq的主要内容,如果未能解决你的问题,请参考以下文章

使用Automapper优化相关子查询

C# linq 如何编写子查询?

实战 EF(LINQ) 如何以子查询的形式来 Join

将 SQL 子查询转换为 Linq 查询

C# linq 查询,每个属性的 where 子查询

LINQ 选择中的 C# 子查询