【问题标题】:Entity Framework Generated SQL for Entity Mapped to a View实体框架为映射到视图的实体生成的 SQL
【发布时间】:2009-04-17 03:16:06
【问题描述】:

我已将 EDM 实体映射到数据库 (SQL Server 2005) 视图。 该实体是一个简单的电影实体,它具有 ID、Name 和 DateInserted 属性,对应于具有以下定义的视图:

选择 iMovieID、vchName、dtInsertDate
FROM dbo.t_Movie WITH (NOLOCK)

t_Movie 表定义如下:

创建表 [dbo].[t_Movie](
[iMovieID] [int] IDENTITY(1,1) 非空,
[vchName] varchar NOT NULL,
[dtInsertDate] [日期时间] NULL,
约束 [PK_t_Movie] 主键集群
( [iMovieID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) 在 [主要]
去吧

当我像这样编写一个简单的 Linq to Entities 查询时:

 var q = from m in context.v_Movie where m.vchName.Contains("Ocean") select m;
            foreach (var movie in q)
            {
                Console.WriteLine("{0}:{1}",movie.iMovieID, movie.vchName);
            }

下面是分析器捕获的Entity框架生成的SQL:

选择
[Extent1].[iMovieID] AS [iMovieID],
[Extent1].[vchName] AS [vchName],
[Extent1].[dtInsertDate] AS [dtInsertDate]
从(选择
[v_Movie].[iMovieID] AS [iMovieID],
[v_Movie].[vchName] AS [vchName],
[v_Movie].[dtInsertDate] AS [dtInsertDate]
FROM [dbo].[v_Movie] AS [v_Movie]) AS [Extent1]
WHERE (CAST(CHARINDEX(N'Ocean', [Extent1].[vchName]) AS int)) > 0

DBA 担心内部 SELECT:

选择
[v_Movie].[iMovieID] AS [iMovieID],
[v_Movie].[vchName] AS [vchName],
[v_Movie].[dtInsertDate] AS [dtInsertDate]
FROM [dbo].[v_Movie] AS [v_Movie]) AS [Extent1]

随着表的增长,随着时间的推移会导致一些严重的性能问题,因为它将视图中的所有行都选择到一个临时表([Extent1])中,然后外部 SELECT 正在从这个临时表中进行选择。

EF 需要这样做的任何特殊原因,是否有任何原因导致以下不可能是生成的 SQL:

选择
[v_Movie].[iMovieID] AS [iMovieID],
[v_Movie].[vchName] AS [vchName],
[v_Movie].[dtInsertDate] AS [dtInsertDate]
FROM [dbo].[v_Movie] AS [v_Movie]
WHERE (CAST(CHARINDEX(N'Ocean', [Extent1].[vchName]) AS int)) > 0

我使用以下 SQL 在表中填充了 100,000 条记录,但在执行 LINQ 查询时没有发现任何性能下降。 Profiler 显示查询运行不到一秒:

开始
声明@counter int
设置@counter = 0
而@counter 开始
设置@counter = @counter + 1

插入 t_Movie(vchName) 值('Movie'+CONVERT(varchar,@counter))
结束
结束

这是一个有效的担忧吗?

附言-

(CAST(CHARINDEX(N'Ocean', [Extent1].[vchName]) AS int)) 这里不用担心,因为我使用的 LINQ to Entities 查询只是为了说明。

任何见解将不胜感激

【问题讨论】:

  • 您需要一个新的 DBA!我希望在过去的 12 年中,他们已经学会了如何识别 子查询 和临时表之间的区别。这里没有需要担心的重大性能问题。我的投票是,这个问题根本不应该留在堆栈上。

标签: c# sql-server entity-framework ado.net


【解决方案1】:

使用 XML 编辑器查看您的 .EDMX 文件。您会在那里找到电影视图的某些内容,其中包含视图的选择语句。删除 select 语句并使视图 XML 的其余部分看起来更像您的表。你得到这个内部选择是因为 EF 天真地认为你试图将列映射到视图中的不同名称而不是默认名称。

【讨论】:

    【解决方案2】:

    我从 MSDN 论坛得到了这个答案,这很有意义:

    Entity Framework Generated SQL

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 2017-02-11
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多