Entity Framework Сгенерированный SQL для сущности, сопоставленной с представлением - PullRequest
2 голосов
/ 17 апреля 2009

Я сопоставил объект EDM с базой данных (SQL Server 2005). Сущность - это простая сущность Movie, которая имеет свойства ID, Name и DateInserted, что соответствует представлению, имеющему следующее определение:

ВЫБРАТЬ iMovieID, vchName, dtInsertDate
ОТ dbo.t_Movie С (NOLOCK)

Таблица t_Movie имеет следующее определение:

CREATE TABLE [dbo]. [T_Movie] (
[iMovieID] [int] IDENTITY (1,1) НЕ НУЛЬ,
[vchName] varchar NOT NULL,
[dtInsertDate] [datetime] NULL,
CONSTRAINT [PK_t_Movie] ПЕРВИЧНЫЙ КЛЮЧ КЛАСТЕРНЫЙ
( [iMovieID] ASC
) С (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [ПЕРВИЧНЫЙ]
) НА [ПЕРВИЧНО]
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, сгенерированный платформой Entity, захваченной профилировщиком:

ВЫБРАТЬ
[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]
ИЗ [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]
ИЗ [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

Я заполнил таблицу 100 000 записей, используя следующий SQL, но не заметил какого-либо снижения производительности при выполнении запроса LINQ. Профилировщик показал, что запрос выполнялся менее чем за секунду:

НАЧАТЬ
объявить @counter int
set @counter = 0
в то время как @counter <100000 <br /> начать
set @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 ]

1 голос
/ 19 апреля 2009

Посмотрите на ваш файл .EDMX с помощью редактора XML. Там вы найдете что-то для просмотра фильма, где есть оператор выбора для просмотра. Удалите оператор select и сделайте остальную часть представления XML больше похожей на ваши таблицы. Вы получаете этот внутренний выбор, потому что EF наивно полагает, что вы пытаетесь сопоставить столбцы с разными именами в представлении, а не с именами по умолчанию.

0 голосов
/ 15 июня 2009

Я получил этот ответ с форумов MSDN, и он имеет смысл:

Entity Framework, сгенерированный SQL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...