Время ожидания Entity Framework

Я получаю тайм-ауты с использованием Entity Framework (EF) при использовании импорта функции, выполнение которого занимает более 30 секунд. Я пробовал следующее, но не смог решить эту проблему:

Я добавил Default Command Timeout=300000 в строку подключения в файле App.Config в проекте, в котором есть файл EDMX, как было предложено здесь.

Вот как выглядит моя строка подключения:

<add 
    name="MyEntityConnectionString" 
    connectionString="metadata=res://*/MyEntities.csdl|res://*/MyEntities.ssdl|
       res://*/MyEntities.msl;
       provider=System.Data.SqlClient;provider connection string=&quot;
       Data Source=trekdevbox;Initial Catalog=StarTrekDatabase;
       Persist Security Info=True;User ID=JamesTKirk;Password=IsFriendsWithSpock;
       MultipleActiveResultSets=True;Default Command Timeout=300000;&quot;"
    providerName="System.Data.EntityClient" />

Я попытался установить CommandTimeout в моем репозитории напрямую следующим образом:

private TrekEntities context = new TrekEntities();

public IEnumerable<TrekMatches> GetKirksFriends()
{
    this.context.CommandTimeout = 180;
    return this.context.GetKirksFriends();
}

Что еще я могу сделать, чтобы отключить EF от тайм-аута? Это происходит только для очень больших наборов данных. Все отлично работает с небольшими наборами данных.

Вот одна из ошибок, которые я получаю:

System.Data.EntityCommandExecutionException: произошла ошибка при выполнении определения команды. Подробнее см. Внутреннее исключение. ---> System.Data.SqlClient.SqlException: истекло время ожидания. Время ожидания истекло до завершения операции или сервер не отвечает.


Хорошо - у меня это работает, и это глупо, что произошло. У меня была строка подключения с Default Command Timeout=300000 и CommandTimeout, установленная на 180. Когда я удалил Default Command Timeout из строки подключения, это сработало. Итак, ответ - вручную установить CommandTimeout в вашем репозитории для вашего объекта контекста следующим образом:

this.context.CommandTimeout = 180;

Видимо установка настроек тайм-аута в строке подключения не влияет на это.


person Halcyon    schedule 03.06.2011    source источник
comment
Удалить из строки подключения   -  person Brian Webster    schedule 04.06.2011
comment
также обратитесь к этому stackoverflow.com/questions / 4396833 / sql-exception-with-net-4-ef   -  person Saif Khan    schedule 04.06.2011
comment
@ hamlin11 В строке подключения EF это необходимо для определения того, какая часть является строкой подключения, а какая - метаданными EF. Оставьте &quot; в строке.   -  person Chev    schedule 04.06.2011
comment
Я предлагаю, прежде чем увеличивать время ожидания, сначала выяснить, почему истекает время ожидания EF. В нашем случае мы поняли, что нам нужно добавить NONCLUSTERED индексов к некоторым таблицам, это решило проблему тайм-аута для нас.   -  person zulucoda    schedule 12.06.2014
comment
Я работаю с поддержкой MS над проблемой тайм-аута SQL - это когда БД размещается в SQL Azure. Мне сказали, что все службы Azure PaaS (веб-сайты PaaS, SQL Azure и т. Д.) Имеют универсальный тайм-аут в 230 секунд, и это всегда имеет приоритет, даже если вы установите тайм-аут вручную. Это сделано для защиты ресурсов многопользовательской инфраструктуры PaaS.   -  person Ian Robertson    schedule 22.08.2017


Ответы (10)


Существует известная ошибка с указанием тайм-аута команды по умолчанию в строке подключения EF.

http://bugs.mysql.com/bug.php?id=56806

Удалите значение из строки подключения и установите его в самом объекте контекста данных. Это сработает, если вы удалите конфликтующее значение из строки подключения.

Entity Framework Core 1.0:

this.context.Database.SetCommandTimeout(180);

Entity Framework 6:

this.context.Database.CommandTimeout = 180;

Entity Framework 5:

((IObjectContextAdapter)this.context).ObjectContext.CommandTimeout = 180;

Entity Framework 4 и ниже:

this.context.CommandTimeout = 180;
person Community    schedule 04.06.2011
comment
Как я могу добиться этого с помощью edmx? - person iroel; 16.06.2014
comment
@iroel Файл модели EDMX не раскрывает эти свойства в контексте данных. Вам необходимо получить доступ к свойству контекста данных, используя один из описанных выше методов. - person Chev; 17.06.2014
comment
В какой версии EntityFramework это исправлено? Я не могу найти для него ошибку EF. - person rudimenter; 31.03.2015
comment
@rudimenter Я не верю, что какая-либо версия исправит это. Я не отправлял сообщение об ошибке команде EF, так что, возможно, никто не позаботился об этом. Не стесняйтесь :) - person Chev; 31.03.2015
comment
Я не считаю, что это ошибка, а скорее по своей природе, см. Раздел «Примечания» здесь ссылка - person Mick P; 19.05.2015
comment
Поскольку некоторые настройки указаны в миллисекундах, а некоторые - в секундах, я просмотрел его здесь, CommandTimeout указывается в секундах. - person JabberwockyDecompiler; 01.10.2015
comment
@MickP Это раздражает. Мне кажется, они должны сначала проверить, указан ли он в строке, а затем not установить тайм-аут для базового поставщика данных, если он присутствует в строке. По крайней мере, дать пользователю какое-то сообщение об ошибке о избыточных тайм-аутах или что-то в этом роде. Просто игнорировать это очень сбивает с толку, о чем свидетельствует популярность этого вопроса. Может быть, сейчас это лучше, но в какой-то момент указание этого в строке и вручную с помощью CommandTimeout не приведет к тому, что ни один из них не будет соблюден. Это еще более неприятно. - person Chev; 01.10.2015
comment
@Alex Ford, знаете ли вы, исправлена ​​ли известная ошибка в .net 4.5? - person ConfusedDeer; 12.04.2016
comment
@ConfusedDeer Я уверен, что он все еще там. - person Chev; 12.04.2016
comment
Была ли ошибка в версии Entity Framework или версии .NET Framework? - person ConfusedDeer; 12.04.2016
comment
Я давно не занимался .NET, но считаю, что ошибка связана с SQL Server. - person Chev; 12.04.2016
comment
В Entity Framework 7 вы можете установить это в конструкторе DbContext / IdentityDbContext: this.Database.SetCommandTimeout(180); - person Thomas Hagström; 18.05.2016
comment
Как установить его только для миграций? - person Ian Warburton; 10.06.2016
comment
Если кто-то знаком с ядром .net, у меня есть вопрос о тайм-ауте .. stackoverflow.com/questions/44427595/ - person Moritz Schmidt; 08.06.2017
comment
Установка свойства CommandTimeout в коде решила мою проблему. Я использую Entity Framework 5 для получения данных из огромной таблицы в моем SQL. Обычно при закрытии DataReader у меня вызывается «Чтение», поэтому я использую команду ниже, чтобы исправить проблему: ((IObjectContextAdapter) this.context) .ObjectContext.CommandTimeout = 1800; - person Loc Huynh; 18.08.2017
comment
Вау ... 5 версий EF и 5 способов настройки CommandTimeout. Ни одна из версий не исправила это в ConnectionString? - person Himalaya Garg; 21.02.2020

Если вы используете DbContext, используйте следующий конструктор для установки тайм-аута команды:

public class MyContext : DbContext
{
    public MyContext ()
    {
        var adapter = (IObjectContextAdapter)this;
        var objectContext = adapter.ObjectContext;
        objectContext.CommandTimeout = 1 * 60; // value in seconds
    }
}
person saille    schedule 17.10.2012
comment
@ErickPetru, так что вы можете легко изменить его на другое количество минут :), также я не был бы слишком удивлен, если компилятор оптимизирует это умножение! - person Joel Verhagen; 30.04.2013
comment
@JoelVerhagen, не удивляйтесь. Вот хорошее объяснение того, когда происходит автоматическая оптимизация: stackoverflow.com/questions/160848/. В этом случае, я предполагаю, что это даже произойдет (поскольку это два буквальных значения), но, честно говоря, я думаю, что код в этом смысле довольно странный. - person Erick Petrucelli; 30.04.2013
comment
мэ ... дети голодают ... кого волнует 1 * 60? - person Timmerz; 17.07.2013
comment
@ErikPetru, на самом деле это очень распространенная практика, которая делает код более читабельным. - person Calvin; 10.12.2013
comment
Как лучше всего справиться с этим, учитывая, что мой производный класс DbContext был автоматически сгенерирован из файла edmx? - person Matt Burland; 30.07.2014
comment
@ matt-burland создайте еще один частичный класс для созданного вами контекста DbContext и реализуйте его в его конструкторе. - person avenmore; 09.09.2014
comment
^^ не может иметь конструктор в частичном классе, как бы эта тренировка? - person Muds; 01.04.2016
comment
У меня такая же реакция, как у Мэтта и Мадса. Как лучше всего справиться с этим, учитывая, что мой производный класс DbContext был автоматически сгенерирован из файла edmx? И не могу иметь конструктор в частичном классе, как бы эта тренировка? - person Bastien Vandamme; 10.03.2017
comment
Я думаю, просто подкласс сгенерированного класса. Конечно, если время ожидания ваших запросов обычно истекает, вам действительно нужно выяснить, почему, но иногда увеличение времени ожидания может вывести вас из затруднительного положения. - person saille; 12.03.2017
comment
Что ж, если вы хотите сделать его читабельным, используйте (int) TimeSpan.FromMinutes (1) .TotalSeconds - person Kyberias; 27.03.2020

Если вы используете DbContext и EF v6 +, в качестве альтернативы вы можете использовать:

this.context.Database.CommandTimeout = 180;
person Paul    schedule 05.11.2013

Обычно я обрабатываю свои операции в рамках транзакции. Как я испытал, недостаточно установить тайм-аут контекстной команды, но транзакции нужен конструктор с параметром тайм-аута. Мне пришлось установить оба значения тайм-аута, чтобы он работал правильно.

int? prevto = uow.Context.Database.CommandTimeout;
uow.Context.Database.CommandTimeout = 900;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(900))) {
...
}

В конце функции я вернул тайм-аут команды к предыдущему значению в prevto.

Использование EF6

person pillesoft    schedule 19.10.2015
comment
Совсем не лучший подход. Раньше я увеличивал объем транзакций, и это стало для меня кошмаром в проекте. В конце концов заменил всю область транзакции одной SAVEChanges () в EF 6+. Проверьте этот coderwall.com/p/ jnniww / - person Moons; 30.05.2019
comment
Этот ответ должен иметь более высокий голос. Я пробовал все разные способы увеличить тайм-аут, но только когда я установил время ожидания ОБЕИХ контекстных команд и область транзакции, это сработало. - person Gang; 20.04.2020

Если вы используете Entity Framework, как я, вам следует определить класс Time out on Startup следующим образом:

 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), o => o.CommandTimeout(180)));
person parismiguel    schedule 01.08.2018

Я знаю, что это очень старый поток, но все еще EF не исправил это. Пользователи, использующие автоматически сгенерированный DbContext, могут использовать следующий код, чтобы установить время ожидания вручную.

public partial class SampleContext : DbContext
{
    public SampleContext()
        : base("name=SampleContext")
    {
        this.SetCommandTimeOut(180);
    }

    public void SetCommandTimeOut(int Timeout)
    {
        var objectContext = (this as IObjectContextAdapter).ObjectContext;
        objectContext.CommandTimeout = Timeout;
    }
}
person Shiva N    schedule 13.11.2017
comment
Добавьте недостающий} в конце части. - person Marc Roussel; 27.05.2021

В .Net Core (NetCore) используйте следующий синтаксис для изменения тайм-аута с 30 секунд по умолчанию на 90 секунд:

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options)
    {
        this.Database.SetCommandTimeout(90); // <-- 90 seconds
    }
}
person N-ate    schedule 20.07.2020

Это то, что я финансирую. Может кому поможет:

Итак, начнем:

Если вы используете LINQ с EF для поиска некоторых точных элементов, содержащихся в списке, например:

await context.MyObject1.Include("MyObject2").Where(t => IdList.Contains(t.MyObjectId)).ToListAsync();

все идет хорошо, пока IdList не будет содержать более одного идентификатора.

Проблема «тайм-аута» возникает, если список содержит только один идентификатор. Чтобы решить эту проблему, используйте условие if для проверки количества идентификаторов в IdList.

Пример:

if (IdList.Count == 1)
{
    result = await entities. MyObject1.Include("MyObject2").Where(t => IdList.FirstOrDefault()==t. MyObjectId).ToListAsync();
}
else
{
    result = await entities. MyObject1.Include("MyObject2").Where(t => IdList.Contains(t. MyObjectId)).ToListAsync();
}

Объяснение:

Просто попробуйте использовать Sql Profiler и проверьте оператор Select, созданный Entity frameeork. …

person tosjam    schedule 15.08.2014

Добавление следующего в мою хранимую процедуру решило мной ошибку тайм-аута:

SET NOCOUNT ON;
SET ARITHABORT ON;
person David Greenfeld    schedule 22.07.2020

Для Entity framework 6 я использую эту аннотацию и отлично работает.

  public partial class MyDbContext : DbContext
  {
      private const int TimeoutDuration = 300;

      public MyDbContext ()
          : base("name=Model1")
      {
          this.Database.CommandTimeout = TimeoutDuration;
      }
       // Some other codes
    }

Параметр CommandTimeout - это целое число, допускающее значение NULL, которое устанавливает значения тайм-аута в секундах; если вы установите значение NULL или не установите его, будет использоваться значение по умолчанию используемого вами поставщика.

person nzrytmn    schedule 16.10.2020