【问题标题】:Making a UNION query more efficient in LINQ在 LINQ 中使 UNION 查询更高效
【发布时间】:2013-01-29 22:30:12
【问题描述】:

我目前正在利用 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 类型,所以首先我返回所有 Table2 关联,其中 Table1 中的一列为空。然后我必须选择我的 Table2 记录,以便我有一个 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]

那么有没有一种更清洁/更有效的方法来做我所描述的事情?谢谢!

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    嗯,一个问题是您的结果可能不会返回与原始 SQL 查询相同的数据。 Union 将选择 distinct 值,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),原因将在here 中详细描述.如果您想要类似于原始查询的内容,请继续使用Union,如上例所示。

    重要的是要记住,LINQ-to-Entities 并不总是能够生成您想要的 SQL,因为它必须以通用方式处理如此多的情况。使用 EF 的好处是它使您的代码更具表现力、更清晰、强类型等,因此您应该首先支持可读性。然后,如果您在分析时确实看到性能问题,那么您可能需要考虑使用其他方法来查询数据。如果您首先分析这两个查询,那么您可能甚至都不关心这个问题的答案。

    【讨论】:

    • 到了这一点,这段代码更干净,运行良好,非常感谢!就您的最后一段而言,我没有将生成的 SQL 作为针对 EF 或任何东西的症结所在;我只是为了这个问题而提供它。正如您指出的那样,我唯一一次真正分析过 SQL 是如果我看到不必要的减速。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多