Време за изчакване на 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

Намерих отговора на Ihf много полезно и аз създавам C# метод за него:

    private int GetRandomNumber(int max, int min, double probabilityPower = 2)
    {
        var randomizer = new Random();
        var randomDouble = randomizer.NextDouble();

        var result = Math.Floor(min + (max + 1 - min) * (Math.Pow(randomDouble, probabilityPower)));
        return (int) result;
    }

Ако probabilityPower е над 1, по-ниските стойности ще бъдат по-чести от по-високите стойности. Ако е между 0 и 1, по-високите стойности ще бъдат по-чести от по-ниските стойности. Ако е 1, резултатите ще бъдат на случаен принцип.

Примери (всички с 1 милион повторения, min = 1, max = 20):


probabilityPower = 1,5

1: 135534 (13.5534%)
2: 76829 (7.6829%)
3: 68999 (6.8999%)
4: 60909 (6.0909%)
5: 54595 (5.4595%)
6: 53555 (5.3555%)
7: 48529 (4.8529%)
8: 44688 (4.4688%)
9: 43969 (4.3969%)
10: 44314 (4.4314%)
11: 40123 (4.0123%)
12: 39920 (3.992%)
13: 40466 (4.0466%)
14: 35821 (3.5821%)
15: 37862 (3.7862%)
16: 35222 (3.5222%)
17: 35902 (3.5902%)
18: 35202 (3.5202%)
19: 33961 (3.3961%)
20: 33600 (3.36%)

probabilityPower = 4

1: 471570 (47.157%)
2: 90114 (9.0114%)
3: 60333 (6.0333%)
4: 46574 (4.6574%)
5: 38905 (3.8905%)
6: 32379 (3.2379%)
7: 28309 (2.8309%)
8: 27906 (2.7906%)
9: 22389 (2.2389%)
10: 21524 (2.1524%)
11: 19444 (1.9444%)
12: 19688 (1.9688%)
13: 18398 (1.8398%)
14: 16870 (1.687%)
15: 15517 (1.5517%)
16: 15871 (1.5871%)
17: 14550 (1.455%)
18: 14635 (1.4635%)
19: 13399 (1.3399%)
20: 11625 (1.1625%)

probabilityPower = 1

1: 51534 (5.1534%)
2: 49239 (4.9239%)
3: 50955 (5.0955%)
4: 47992 (4.7992%)
5: 48971 (4.8971%)
6: 50456 (5.0456%)
7: 49282 (4.9282%)
8: 51344 (5.1344%)
9: 50841 (5.0841%)
10: 48548 (4.8548%)
11: 49294 (4.9294%)
12: 51795 (5.1795%)
13: 50583 (5.0583%)
14: 51020 (5.102%)
15: 51060 (5.106%)
16: 48632 (4.8632%)
17: 48568 (4.8568%)
18: 50039 (5.0039%)
19: 49863 (4.9863%)
20: 49984 (4.9984%)

probabilityPower = 0,5

1: 3899 (0.3899%)
2: 5818 (0.5818%)
3: 12808 (1.2808%)
4: 17880 (1.788%)
5: 23109 (2.3109%)
6: 26469 (2.6469%)
7: 33435 (3.3435%)
8: 35243 (3.5243%)
9: 42276 (4.2276%)
10: 47235 (4.7235%)
11: 52907 (5.2907%)
12: 58107 (5.8107%)
13: 63719 (6.3719%)
14: 66266 (6.6266%)
15: 72708 (7.2708%)
16: 79257 (7.9257%)
17: 81830 (8.183%)
18: 87243 (8.7243%)
19: 90958 (9.0958%)
20: 98833 (9.8833%)

probabilityPower = 0,4

1: 917 (0.0917%)
2: 3917 (0.3917%)
3: 3726 (0.3726%)
4: 10679 (1.0679%)
5: 13092 (1.3092%)
6: 17306 (1.7306%)
7: 22838 (2.2838%)
8: 29221 (2.9221%)
9: 35832 (3.5832%)
10: 38422 (3.8422%)
11: 47800 (4.78%)
12: 53431 (5.3431%)
13: 63791 (6.3791%)
14: 69460 (6.946%)
15: 75313 (7.5313%)
16: 86536 (8.6536%)
17: 95082 (9.5082%)
18: 103440 (10.344%)
19: 110203 (11.0203%)
20: 118994 (11.8994%)
  -  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 - това е, когато DB се хоства в SQL Azure. Казаха ми, че всички PaaS услуги на Azure (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
Тъй като някои настройки са в ms, а други в s, потърсих го тук, CommandTimeout е в секунди. - person JabberwockyDecompiler; 01.10.2015
comment
@MickP Това е досадно. Струва ми се, че първо трябва да проверят дали такъв е предоставен в низа, а след това да не задават времето за изчакване на основния доставчик на данни, ако такъв присъства в низа. Най-малкото дайте на потребителя някакво съобщение за грешка относно излишни изчаквания или нещо подобно. Простото игнориране е супер объркващо, както се вижда от популярността на този въпрос. Може би сега е по-добре, но в един момент указването му в низа и ръчно с 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
Грешката във версията на рамката на обекта ли беше или във версията на .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 core, имам въпрос, който е относно времето за изчакване.. 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 на клас 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 е nullable цяло число, което задава стойности за изчакване като секунди, ако зададете null или не зададете, той ще използва стойността по подразбиране на доставчика, който използвате.

person nzrytmn    schedule 16.10.2020