在 LINQ 中提高 UNION 查询的效率
本文关键字:查询 效率 UNION LINQ | 更新日期: 2023-09-27 17:56:25
我目前正在利用EF进行一个项目,我想知道是否有更有效或更干净的方法来处理我下面的内容。
在SQL Server中,我可以通过执行以下操作来获取所需的数据:
SELECT tbl2.* FROM
dbo.Table1 tbl
INNER JOIN dbo.Table2 tbl2 ON tbl.Column = tbls2.Colunm
WHERE tbl.Column2 IS NULL
UNION
SELECT * FROM
dbo.Table2
WHERE Column2 = value
非常直截了当。 但是在 LINQ 中,我有一些看起来像这样的东西:
var results1 = Repository.Select<Table>()
.Include(t => t.Table2)
.Where(t => t.Column == null);
var table2Results = results1.Select(t => t.Table2);
var results2 = Repository.Select<Table2>().Where(t => t.Column2 == "VALUE");
table2Results = table2Results.Concat(results2);
return results2.ToList();
首先,包含此代码的方法的返回类型是 IEnumerable
这对我来说似乎非常健谈,我认为,有一种更好的方法来做我想要实现的目标。生成的SQL并不可怕(为了可读性,我省略了列列表)
SELECT
[UnionAll1].*
FROM (SELECT
[Extent2].*
FROM [dbo].[Table1] AS [Extent1]
INNER JOIN [dbo].[Table2] AS [Extent2] ON [Extent1].[Column] = [Extent2].[Column]
WHERE [Extent1].[Column2] IS NULL
UNION ALL
SELECT
[Extent3].*
FROM [dbo].[Table2] AS [Extent3]
WHERE VALUE = [Extent3].[Column]) AS [UnionAll1]
那么有没有一种更清洁/更有效的方式来完成我所描述的事情? 谢谢!
嗯,一个问题是你的结果可能不会返回与原始SQL查询相同的数据。 Union
将选择不同的值,Union All
将选择所有值。首先,我认为您的代码可以像这样更清晰:
// Notice the lack of "Include". "Include" only states what should be returned
// *with* the original type, and is not necessary if you only need to select the
// individual property.
var firstResults = Repository.Select<Table>()
.Where(t => t.Column == null)
.Select(t => t.Table2);
var secondResults = Repository.Select<Table2>()
.Where(t => t.Column2 == "Value");
return firstResults.Union(secondResults);
如果您知道此查询中不可能有重复项,请在最后一行改用Concat
(这将生成您在当前代码中看到的UNION ALL
),原因在此处进行了更详细的描述。如果需要类似于原始查询的内容,请继续使用Union
,如上例所示。
记住,LINQ-to-Entities 并不总是能够生成所需的 SQL,因为它必须以通用方式处理如此多的情况。使用 EF 的好处是,它使代码更具表现力、更清晰、更强类型等,因此应首先支持可读性。然后,如果在分析时确实看到性能问题,则可能需要考虑查询数据的替代方法。如果您首先分析这两个查询,那么您甚至可能不关心这个问题的答案。