Как увеличить скорость выполнения запроса в EF - PullRequest
1 голос
/ 26 мая 2019

Метод FindByQueryAsNoTracking() приведен ниже:

public IEnumerable<T> FindByAsNoTracking(Expression<Func<T, bool» predicate)
{
    IQueryable<T> query = Dbset.Where(predicate).AsNoTracking().AsQueryable();
        return query;
}

, если мы используем FindByAsQuery, что ниже:

public IQueryable<T> FindByQuery(Expression<Func<T, bool» predicate)
{
    IQueryable<T> query = Dbset.Where(predicate).AsQueryable();
    return query;
}

Скорость улучшится ??

Ответы [ 2 ]

3 голосов
/ 26 мая 2019
AsNoTracking(IQueryable)

Возвращает новый запрос, в котором возвращенные сущности не будут кэшироваться в DbContext или ObjectContext . Этот метод работает путем вызова метода AsNoTracking базового объекта запроса. Если базовый объект запроса не имеет AsNoTracking метода, то вызов этого метода не будет иметь никакого эффекта.

Нет запросов на отслеживание

5.1 Отключение отслеживания изменений для уменьшения накладных расходов на управление состоянием Если Вы находитесь в сценарии только для чтения и хотите избежать накладных расходов загружая объекты в ObjectStateManager, вы можете выдать «Нет «Отслеживание» запросов. Отслеживание изменений можно отключить по запросу уровень.

Обратите внимание, что, отключив отслеживание изменений, вы эффективно отключение кеша объектов Когда вы запрашиваете сущность, мы не можем пропустить материализацию, потянув ранее материализованный запрос результаты из ObjectStateManager. Если вы неоднократно запрашиваете для тех же сущностей в том же контексте, вы можете увидеть выигрыш в производительности от включения отслеживания изменений.

При запросах с использованием экземпляров ObjectContext, ObjectQuery и ObjectSet запомнит MergeOption, как только он будет установлен, и запросы, которые составленный на них наследует эффективный MergeOption родительского запрос. При использовании DbContext отслеживание можно отключить, вызвав Модификатор AsNoTracking () в DbSet.

Короче говоря, да, используя AsNoTracking, вы получаете лучшую производительность, особенно когда собираетесь загружать много строк данных, но не забывайте, что это не влияет на сгенерированный SQL запрос, а только увеличивает производительность в .NET.

AsNoTracking vs Tracking

enter image description here

пс: Графики взяты из StaticVoid blog .

2 голосов
/ 29 июня 2019

Вам необходимо использовать скомпилированные запросы (LINQ to Entities)

Пожалуйста, укажите введите описание ссылки здесь

И еще одна вещь, если вы хотите дочерние данные, тогда установите LazyLoding = true

по умолчанию LazyLoding = true в классе EntityFramework DBContext

Ленивая загрузка в Entity Framework

Ленивая загрузка задерживает загрузку связанных данных, пока вы специально не запросите их. Это противоположность нетерпеливой загрузки. Например, сущность Student содержит сущность StudentAddress . При отложенной загрузке контекст сначала загружает данные сущности Student из базы данных , затем загружает сущность StudentAddress при доступе к StudentAddress свойство, как показано ниже.

using (var ctx = new SchoolDBEntities())
{
    //Loading students only
    IList<Student> studList = ctx.Students.ToList<Student>();

    Student std = studList[0];

   //Loads Student address for particular Student only (seperate SQL query)
   StudentAddress add = std.StudentAddress;
}

Приведенный выше код приведет к двум запросам SQL. Сначала будут выбраны все студенты:

SELECT 
[Extent1].[StudentID] AS [StudentID], 
[Extent1].[StudentName] AS [StudentName], 
[Extent1].[StandardId] AS [StandardId]
FROM [dbo].[Student] AS [Extent1]

Затем он отправит следующий запрос, когда мы получим ссылку на StudentAddress:

    exec sp_executesql N'SELECT 
[Extent1].[StudentID] AS [StudentID], 
[Extent1].[Address1] AS [Address1], 
[Extent1].[Address2] AS [Address2], 
[Extent1].[City] AS [City], 
[Extent1].[State] AS [State]
FROM [dbo].[StudentAddress] AS [Extent1]
WHERE [Extent1].[StudentID] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=1

Отключить отложенную загрузку

Мы можем отключить отложенную загрузку для определенного объекта или контекста. Чтобы отключить отложенную загрузку для определенного свойства, не делайте его виртуальным. Чтобы отключить отложенную загрузку для всех объектов в контексте, установите для его свойства конфигурации значение false.

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Core.Objects;
using System.Linq;

public partial class SchoolDBEntities : DbContext
{
    public SchoolDBEntities(): base("name=SchoolDBEntities")
    {
        this.Configuration.LazyLoadingEnabled = false;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    }
}

Правила для отложенной загрузки:

  • context.Configuration.ProxyCreationEnabled должно быть истинным.

  • context.Configuration.LazyLoadingEnabled должно быть истинным.

  • Свойство навигации должно быть определено как общедоступное, виртуальное. Контекст
    НЕ будет выполнять отложенную загрузку, если свойство не определено как виртуальное.

...