实体框架为实体映射到视图生成的SQL

时间:2009-04-17 03:16:07

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

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

  

SELECT iMovieID,vchName,dtInsertDate
  来自dbo.t_Movie WITH(NOLOCK)

表t_Movie具有以下定义:

  

CREATE TABLE [dbo]。[t_Movie](
      [iMovieID] [int] IDENTITY(1,1)NOT NULL,
      [vchName] varchar NOT NULL,
      [dtInsertDate] [datetime] NULL,
   约束[PK_t_Movie] PRIMARY KEY CLUSTERED
  (       [iMovieID] ASC
  )WITH(PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON)ON [PRIMARY]
  )[主要]
  GO

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

 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);
            }

以下是由探查器捕获的实体框架生成的SQL:

  

选择
  [Extent1]。[iMovieID] AS [iMovieID],
  [Extent1]。[vchName] AS [vchName],
  [Extent1]。[dtInsertDate] AS [dtInsertDate]
  FROM(选择
        [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担心内部选择:

  

选择
  [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]
        来自[dbo]。[v_Movie] AS [v_Movie]
  WHERE(CAST(CHARINDEX(N'Ocean',[Extent1]。[vchName])AS int))> 0

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

  

BEGIN
  声明@counter int
      设置@counter = 0
      而@counter< 100000个
      开始
        设置@counter = @counter + 1

        INSERT INTO t_Movie(vchName)值('Movie'+ CONVERT(varchar,@ counter))
      结束
  END

这是一个有效的问题吗?

P.S -

  

(CAST(CHARINDEX(N'Ocean',[Extent1]。[vchName])AS int))   这里不是问题,因为我使用的LINQ to Entities查询仅用于说明。

非常感谢任何见解

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

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

Entity Framework Generated SQL