3

我目前正在开发一个利用 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> 类型,因此首先我返回所有 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]

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

4

1 回答 1

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您在当前代码中看到的),原因在此处进行了更详细的描述。如果您想要类似于原始查询的内容,请继续使用Union上面示例中的内容。

It's important to remember that LINQ-to-Entities is not always going to be able to produce the SQL that you desire, since it has to handle so many cases in a generic fashion. The benefit of using EF is that it makes your code a lot more expressive, clearer, strongly typed, etc. so you should favor readability first. Then, if you actually see a performance problem when profiling, then you might want to consider alternate ways to query for the data. If you profile the two queries first, then you might not even care about the answer to this question.

于 2013-01-29T14:27:26.900 回答