简体   繁体   English

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

[英]Entity Framework Generated SQL for Entity Mapped to a View

I've mapped an EDM entity to a database(SQL Server 2005) View. 我已将EDM实体映射到数据库(SQL Server 2005)视图。 The entity is a simple Movie Entity which has properties of ID, Name and DateInserted which corresponds to a View which has the following definition: 该实体是一个简单的电影实体,具有ID,Name和DateInserted属性,该属性对应于具有以下定义的View:

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

The table t_Movie has the following definition: 表t_Movie具有以下定义:

CREATE TABLE [dbo].[t_Movie]( 创建表[dbo]。[t_Movie](
[iMovieID] [int] IDENTITY(1,1) NOT NULL, [iMovieID] [int] IDENTITY(1,1)NOT NULL,
[vchName] varchar NOT NULL, [vchName] varchar NOT NULL,
[dtInsertDate] [datetime] NULL, [dtInsertDate] [datetime] NULL,
CONSTRAINT [PK_t_Movie] PRIMARY KEY CLUSTERED 约束[PK_t_Movie]主键
( [iMovieID] ASC ([iMovieID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, )(PAD_INDEX = OFF,STATISTICS_NORECOMPUTE = OFF,IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ALLOW_ROW_LOCKS = ON,ALLOW_PAGE_LOCKS = ON)开启[PRIMARY]
) ON [PRIMARY] )在[PRIMARY]上
GO

When I write a simple Linq to Entities Query like so: 当我像这样向实体查询编写简单的Linq时:

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

Here is the SQL generated by the Entity framework captured by the profiler: 这是由探查器捕获的Entity框架生成的SQL:

SELECT 选择
[Extent1].[iMovieID] AS [iMovieID], [Extent1]。[iMovieID] AS [iMovieID],
[Extent1].[vchName] AS [vchName], [Extent1]。[vchName] AS [vchName],
[Extent1].[dtInsertDate] AS [dtInsertDate] [Extent1]。[dtInsertDate] AS [dtInsertDate]
FROM (SELECT 从(选择
[v_Movie].[iMovieID] AS [iMovieID], [v_Movie]。[iMovieID]作为[iMovieID],
[v_Movie].[vchName] AS [vchName], [v_Movie]。[vchName] AS [vchName],
[v_Movie].[dtInsertDate] AS [dtInsertDate] [v_Movie]。[dtInsertDate] AS [dtInsertDate]
FROM [dbo].[v_Movie] AS [v_Movie]) AS [Extent1] FROM [dbo]。[v_Movie] AS [v_Movie])AS [Extent1]
WHERE (CAST(CHARINDEX(N'Ocean', [Extent1].[vchName]) AS int)) > 0 在哪里(CAST(CHARINDEX(N'Ocean',[Extent1]。[vchName])AS int))> 0

The DBA has concern that the Inner SELECT: DBA担心内部选择:

SELECT 选择
[v_Movie].[iMovieID] AS [iMovieID], [v_Movie]。[iMovieID]作为[iMovieID],
[v_Movie].[vchName] AS [vchName], [v_Movie]。[vchName] AS [vchName],
[v_Movie].[dtInsertDate] AS [dtInsertDate] [v_Movie]。[dtInsertDate] AS [dtInsertDate]
FROM [dbo].[v_Movie] AS [v_Movie]) AS [Extent1] FROM [dbo]。[v_Movie] AS [v_Movie])AS [Extent1]

will cause some serious performance issues over time as the table grows since its selecting all the rows from the view into a temp table([Extent1]) and then the outer SELECT is selecting from this temp table. 随着表的增长,随着时间的流逝将导致一些严重的性能问题,因为它从视图中选择了所有行到临时表([Extent1]),然后外部SELECT从该临时表中进行选择。

Any particular reason why EF needs to do this, is there any reason why the following could not have been the generated SQL: EF需要执行此操作的任何特殊原因,是为什么不能生成以下SQL的任何原因:

SELECT 选择
[v_Movie].[iMovieID] AS [iMovieID], [v_Movie]。[iMovieID]作为[iMovieID],
[v_Movie].[vchName] AS [vchName], [v_Movie]。[vchName] AS [vchName],
[v_Movie].[dtInsertDate] AS [dtInsertDate] [v_Movie]。[dtInsertDate] AS [dtInsertDate]
FROM [dbo].[v_Movie] AS [v_Movie] 来自[dbo]。[v_Movie] AS [v_Movie]
WHERE (CAST(CHARINDEX(N'Ocean', [Extent1].[vchName]) AS int)) > 0 在哪里(CAST(CHARINDEX(N'Ocean',[Extent1]。[vchName])AS int))> 0

I populated the table with 100,000 records using the following SQL but did not notice any performance degradation when executing the LINQ query. 我使用以下SQL向表中填充了100,000条记录,但是执行LINQ查询时没有发现性能下降。 Profiler showed that the query ran under a second: Profiler显示查询运行了不到一秒钟:

BEGIN 开始
declare @counter int 声明@counter int
set @counter = 0 设置@counter = 0
while @counter < 100000 而@counter <100000
begin 开始
set @counter = @counter + 1 设置@counter = @counter + 1

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

Is this a valid concern? 这是一个有效的问题吗?

PS - PS-

(CAST(CHARINDEX(N'Ocean', [Extent1].[vchName]) AS int)) is not a concern here since the LINQ to Entities query I've used is just for illustration. (CAST(CHARINDEX(N'Ocean',[Extent1]。[vchName])AS int))在这里不是问题,因为我使用的LINQ to Entities查询仅用于说明。

Any insights would be much appreciated 任何见解将不胜感激

Look at your .EDMX file using an XML Editor. 使用XML编辑器查看您的.EDMX文件。 You will find something there for the movie view where it has a select statement for the view. 您将在电影视图中找到一些内容,并在其中找到该视图的选择语句。 Remove the select statement and make the rest of the view XML look more like your tables. 删除select语句,并使其余视图XML看起来更像您的表。 You are getting this inner select because EF things naively that you are trying to map the columns to different names in the view rather than the default names. 之所以得到这个内部选择,是因为EF天真地尝试将列映射到视图中的不同名称而不是默认名称。

I got this answer from MSDN forums and it makes perfect sense: 我从MSDN论坛上得到了这个答案,这很有意义:

Entity Framework Generated SQL 实体框架生成的SQL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM