Таймауты Entity Framework


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

добавил Default Command Timeout=300000 в строке подключения в приложение.Конфигурации файл в проекте, который имеет файл 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 от тайм-аута? Это происходит только для очень больших наборов данных. Все прекрасно работает с небольшими наборами данных.

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

Система.Данные.SqlClient.SqlException: тайм-аут истек. Таймаут истекло до завершения операции или сервер не отвечает.

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

this.context.CommandTimeout = 180;

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

7 267

7 ответов:

существует известная ошибка с указанием таймаута команды по умолчанию в строке подключения 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;

сущность Основа 5:

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

Entity Framework 4 и ниже:

this.context.CommandTimeout = 180;

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

public class MyContext : DbContext
{
    public MyContext ()
    {
        var adapter = (IObjectContextAdapter)this;
        var objectContext = adapter.ObjectContext;
        objectContext.CommandTimeout = 1 * 60; // value in seconds
    }
}

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

this.context.Database.CommandTimeout = 180;

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

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

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

С помощью EF6

Я знаю, что это очень старый поток работает, но все еще 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;
    }

это то, что я финансировал. Может быть, это кому-то поможет:

Так вот:

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

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

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

проблема "тайм-аут" выходит, если список содержит только один ID. Чтобы устранить проблему, используйте условие if для проверки количества идентификаторов в списке идентификаторов.

пример:

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 frameork. ...

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

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