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

2

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

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

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

CREATE TABLE [dbo]. [t_Movie] (
    [iMovieID] [int] ИДЕНТИФИКАЦИЯ (1,1) NOT NULL,
    [vchName] varchar NOT NULL,
    [dtInsertDate] [datetime] NULL,
 CONSTRAINT [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]
) ON [PRIMARY]
GO

Когда я пишу простой запрос 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);
            }

Вот SQL, сгенерированный инфраструктурой Entity, захваченной профилировщиком:

ВЫБЕРИТЕ
[Extent1]. [IMovieID] AS [iMovieID],
[Extent1]. [VchName] AS [vchName],
[Extent1]. [DtInsertDate] AS [dtInsertDate]
FROM (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]
WHERE (CAST (CHARINDEX (N'Ocean ', [Extent1]. [VchName]) AS int)) > 0

Администратор базы данных обеспокоен тем, что внутренний 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

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

НАЧАТЬ
declare @counter int
    set @counter = 0
    в то время как @counter < 100000
    начать
      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, который я использовал, просто для иллюстрации.

Любые идеи были бы очень оценены

Теги:
sql-server
entity-framework
ado.net

2 ответа

1

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

0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню