在LINQ中使UNION查询更有效

时间:2013-01-29 13:59:38

标签: c# linq

我目前正在开发一个利用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&lt;表2&gt;所以首先我得到Table1关联,其中Table1中的列为null。然后我必须选择我的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]

那么有更清洁/更有效的方式来完成我所描述的内容吗?谢谢!

1 个答案:

答案 0 :(得分:2)

嗯,有一个问题是您的结果可能不会返回与原始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),原因如下所述详情here。如果您想要与原始查询类似的内容,请继续使用上面示例中的Union

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