Таймауты 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="
Data Source=trekdevbox;Initial Catalog=StarTrekDatabase;
Persist Security Info=True;User ID=JamesTKirk;Password=IsFriendsWithSpock;
MultipleActiveResultSets=True;Default Command Timeout=300000;""
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 ответов:
существует известная ошибка с указанием таймаута команды по умолчанию в строке подключения 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. ...