从实体框架中的视图中进行选择

时间:2017-05-23 20:34:08

标签: c# entity-framework linq expression-trees

我试图通过直接方式从视图中选择一些列,如下面的代码片段

var q = new TDSViewConnection();
var trials = q.progressive_filtering_lookup_decoded_v
              .Where(z => z.source == "") 
              .Select(z => z.trial_id);

为上面的表达式生成的SQL语句如下所示

SELECT 
    [Extent1].[trial_id] AS [trial_id]
FROM 
    (SELECT 
         [progressive_filtering_lookup_decoded_v].[master_protocol_id] AS [master_protocol_id], 
         [progressive_filtering_lookup_decoded_v].[trial_id] AS [trial_id], 
         [progressive_filtering_lookup_decoded_v].[source] AS [source], 
         [progressive_filtering_lookup_decoded_v].[discipline_code] AS [discipline_code], 
         [progressive_filtering_lookup_decoded_v].[crop_team_code] AS [crop_team_code], 
         [progressive_filtering_lookup_decoded_v].[crop_name] AS [crop_name], 
         [progressive_filtering_lookup_decoded_v].[pest_name] AS [pest_name], 
         [progressive_filtering_lookup_decoded_v].[country_code] AS [country_code], 
         [progressive_filtering_lookup_decoded_v].[year] AS [year]
     FROM 
         [dbo].[progressive_filtering_lookup_decoded_v] AS [progressive_filtering_lookup_decoded_v]) AS [Extent1]
WHERE 
    N'' = [Extent1].[source]

问题是为什么有两个选择陈述?我认为这应该只是一个声明。

2 个答案:

答案 0 :(得分:1)

正如其他用户发布的那样,您生成的查询是投影结果或完整查询的子集。因此,查询引擎会将完整对象视为源,并且只需从中选择所需的项,从而生成子查询。

如果您查看SQL Server中的查询计划性能,那么以EF执行查询的方式运行查询与您可能期望查看它的方式之间通常没有真正的区别。

这里的主要好处是,由于您只需要一列,因此EF确保从数据库返回的全部内容。通常我发现确保您拥有最小的结果集是所需的功能。通过更复杂的预测,这一点变得更加明显。

答案 1 :(得分:0)

使用Entity Framework,您将在LINQ语句表达的内容下获得SQL生成。在我看来,你的LINQ语句是根据你的代码的初步部分执行它的第一次选择,然后当你再次使用'。选择'关键字,您实际上是对先前检索的结果集执行子查询。

换句话说:var trials = q.progressive_filtering_lookup_decoded_v.Where(z => z.source == "")是初始查询,它将返回结果集。

然后您正在运行.Select(z => z.trial_id);,它使用您的第一个结果集作为起点运行单独的查询。

这就是您在生成的SQL中看到两个select语句的原因。