Почему Entity Framework создает вложенные запросы SELECT с дублированием SQL? - PullRequest
0 голосов
/ 28 января 2020

Я использую Ведение Entity Framework , чтобы посмотреть на SQL, сгенерированный моими запросами. Во многих случаях производимый SQL имеет операторы SELECT, работающие с подзапросами, идентичными исходному запросу. Например:

Следующий код EF:

context.PodcastItems
.Where(p => p.ID == sourceFeedUpdateItemId)
.Select(p => new NewPodcastItemSubsetDTO
{
   ID = p.ID,
   ItemID = p.ItemID,
   ItemTitle = p.ItemTitle,
   ItemSummary = p.ItemSummary,
   PermalinkUrl = p.PermalinkUrl,
   ItemPublishedDate = p.ItemPublishedDate,
   AudioFileUrl = p.AudioFileUrl,
   FileSize = p.FileSize,
   Duration = p.Duration
}).SingleOrDefault();

создает следующее SQL:

SELECT
    [Limit1].[ID] AS [ID],
    [Limit1].[ItemID] AS [ItemID],
    [Limit1].[ItemTitle] AS [ItemTitle],
    [Limit1].[ItemSummary] AS [ItemSummary],
    [Limit1].[PermalinkUrl] AS [PermalinkUrl],
    [Limit1].[ItemPublishedDate] AS [ItemPublishedDate],
    [Limit1].[AudioFileUrl] AS [AudioFileUrl],
    [Limit1].[FileSize] AS [FileSize],
    [Limit1].[Duration] AS [Duration]
    FROM ( SELECT TOP (2)
        [Extent1].[ID] AS [ID],
        [Extent1].[ItemID] AS [ItemID],
        [Extent1].[ItemTitle] AS [ItemTitle],
        [Extent1].[ItemSummary] AS [ItemSummary],
        [Extent1].[PermalinkUrl] AS [PermalinkUrl],
        [Extent1].[AudioFileUrl] AS [AudioFileUrl],
        [Extent1].[FileSize] AS [FileSize],
        [Extent1].[Duration] AS [Duration],
        [Extent1].[ItemPublishedDate] AS [ItemPublishedDate]
        FROM [dbo].[PodcastItems] AS [Extent1]
        WHERE [Extent1].[ID] = @p__linq__0
    )  AS [Limit1]

и этот код:

string content = context.PodcastItems
.Where(p => p.ID == sourceFeedUpdateItemId)
.Select(p => p.ItemContentCleansed)
.SingleOrDefault();

производит:

SELECT
    [Limit1].[ItemContentCleansed] AS [ItemContentCleansed]
    FROM ( SELECT TOP (2)
        [Extent1].[ItemContentCleansed] AS [ItemContentCleansed]
        FROM [dbo].[PodcastItems] AS [Extent1]
        WHERE [Extent1].[ID] = @p__linq__0
    )  AS [Limit1]
SELECT
    [Limit1].[ItemContentCleansed] AS [ItemContentCleansed]
    FROM ( SELECT TOP (2)
        [Extent1].[ItemContentCleansed] AS [ItemContentCleansed]
        FROM [dbo].[PodcastItems] AS [Extent1]
        WHERE [Extent1].[ID] = @p__linq__0
    )  AS [Limit1]
SELECT
    [Limit1].[ItemContentCleansed] AS [ItemContentCleansed]
    FROM ( SELECT TOP (2)
        [Extent1].[ItemContentCleansed] AS [ItemContentCleansed]
        FROM [dbo].[PodcastItems] AS [Extent1]
        WHERE [Extent1].[ID] = @p__linq__0
    )  AS [Limit1]
SELECT
    [Limit1].[ItemContentCleansed] AS [ItemContentCleansed]
    FROM ( SELECT TOP (2)
        [Extent1].[ItemContentCleansed] AS [ItemContentCleansed]
        FROM [dbo].[PodcastItems] AS [Extent1]
        WHERE [Extent1].[ID] = @p__linq__0
    )  AS [Limit1]
SELECT
    [Limit1].[ItemContentCleansed] AS [ItemContentCleansed]
    FROM ( SELECT TOP (2)
        [Extent1].[ItemContentCleansed] AS [ItemContentCleansed]
        FROM [dbo].[PodcastItems] AS [Extent1]
        WHERE [Extent1].[ID] = @p__linq__0
    )  AS [Limit1]

Конечно, кажется, что на выполнение sh ... ничего не затрачивается много дополнительных циклов

Почему это может происходить?

1 Ответ

0 голосов
/ 28 января 2020

Проверьте файл EDMX, возможно, ваша сущность определена через DefiningQuery, например:

<!-- SSDL content -->
<edmx:StorageModels>
  <Schema Namespace="SchoolModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
    <EntityContainer Name="SchoolModelStoreContainer">
       <EntitySet Name="GradeReport" EntityType="SchoolModel.Store.GradeReport">
          <DefiningQuery>
            SELECT CourseID, Grade, FirstName, LastName
            FROM StudentGrade
          </DefiningQuery>
      </EntitySet>

Вам нужно заменить его без DefiningQuery только на EntitySet:

 <EntitySet Name="Course" EntityType="SchoolModel.Store.Course" store:Type="Tables" Schema="dbo" />

Подробнее в статье .

...