2012-10-08 11 views
121

Moje polecenie zatrzymuje limit czasu. więc muszę zmienić domyślną wartość limitu czasu polecenia. Znalazłem "myDb.Database.Connection.ConnectionTimeout", ale jest to tylko do odczytu.Ustaw limit czasu bazy danych w Entity Framework

Jak ustawić limit czasu polecenia w Entity Framework 5?

+16

FYI, na EF6, 'Database.CommandTimeout' nie jest już tylko do odczytu – itsho

+1

@itsho Mówił on o' Database.Connection.ConnectionTimeout'. W każdym razie, powiedziałbym, że 'Database.CommandTimeout' jest właściwą rzeczą w przypadku, gdy twoje zapytanie jest time-outowe (wyjątek' System.Data.Entity.Core.EntityCommandExecutionException' zawierający 'System.Data.SqlClient.SqlException: Timeout minął. '). –

+0

Możliwy duplikat [Entity Framework Timeouts] (http://stackoverflow.com/questions/6232633/entity-framework-timeouts) –

Odpowiedz

149

Spróbuj na context:

public class MyDatabase : DbContext 
{ 
    public MyDatabase() 
     : base(ContextHelper.CreateConnection("Connection string"), true) 
    { 
     ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 180; 
    } 
} 

Jeśli chcesz określić limit czasu w ciągu połączenia, użyj parametru Connection Timeout jak w następujący ciąg połączenia:

<connectionStrings> 

<add name="AdventureWorksEntities" 
connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl; 
provider=System.Data.SqlClient;provider connection string='Data Source=localhost; 
Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60; 
multipleactiveresultsets=true'" providerName="System.Data.EntityClient" /> 

</connectionStrings> 

Źródło: How to: Define the Connection String

+1

Zalecam używanie wersji łańcucha połączeń tak, jakbyś próbował uzyskać dostęp do 'ObjectContext' w tym konstruktorze, czasami polecenia [PowerShell/NuGet konsoli nie powiedzie się w sposób cykliczny] (http://stackoverflow.com/questions/15169281/ odbiór-modelu-backing-kontekst-kontekst-zmienił-na-dodać-migrati). –

+91

Connection Timeout i CommandTimeout i dwie osobne rzeczy. Ustawienie ciągu połączenia, Connection Timeout, nie ma wpływu na czas uruchamiania komendy (CommandTimeout). –

+0

Może być, ponieważ jest to odpowiedź ma rok, ale 'Connection Timeout' zwiększa" EntityException ". Podstawowy dostawca nie powiodło się na Open". Rzeczywista poprawna wartość to 'Connect Timeout', ale mimo to wydaje się, że została ona zignorowana przez EF. – Lankymart

17

Moje kontekstowe loo kontekstowe jaw jak:

public partial class MyContext : DbContext 
{ 
    public MyContext (string ConnectionString) 
     : base(ConnectionString) 
    { 
     this.SetCommandTimeOut(300); 
    } 

    public void SetCommandTimeOut(int Timeout) 
    { 
     var objectContext = (this as IObjectContextAdapter).ObjectContext; 
     objectContext.CommandTimeout = Timeout; 
    } 
} 

Wyszedłem SetCommandTimeOut publicznych to tylko rutynowe muszę zająć dużo czasu (więcej niż 5 minut) modyfikować zamiast globalnego timeout.

7

samo jak innych odpowiedzi, ale jako metodę rozszerzenia:

static class Extensions 
{ 
    public static void SetCommandTimeout(this IObjectContextAdapter db, TimeSpan? timeout) 
    { 
     db.ObjectContext.CommandTimeout = timeout.HasValue ? (int?) timeout.Value.TotalSeconds : null; 
    } 
} 
+0

i jak mogę nazwać tę metodę rozszerzenia? –

8

ja przedłużony odpowiedź Ronniego z płynną realizację, dzięki czemu można go używać tak:

dm.Context.SetCommandTimeout(120).Database.SqlQuery...

public static class EF 
{ 
    public static DbContext SetCommandTimeout(this DbContext db, TimeSpan? timeout) 
    { 
     ((IObjectContextAdapter)db).ObjectContext.CommandTimeout = timeout.HasValue ? (int?) timeout.Value.TotalSeconds : null; 

     return db; 
    } 

    public static DbContext SetCommandTimeout(this DbContext db, int seconds) 
    { 
     return db.SetCommandTimeout(TimeSpan.FromSeconds(seconds)); 
    } 
} 
7

W wygenerowanym kodzie konstruktora należy wywołać OnContextCreated()

Dodałem tę klasę do częściowego rozwiązania problemu:

partial class MyContext: ObjectContext 
{ 
    partial void OnContextCreated() 
    { 
     this.CommandTimeout = 300; 
    } 
} 
123

Można użyć DbContext.Database.CommandTimeout = 180;

Jest to dość proste i nie ma wymaganej obsady.

+1

Bardzo przydatne dla nas, które używają formy "Fluent API" EF. – GoldBishop

+1

Cieszę się, że to zauważyłem, zawsze byłem (niepotrzebnie!) Nieufny wobec obsady. –

+0

jak dla mnie, działa nawet na EF5, dzięki! – Fragment

7

dla bazy pierwszego Aproach:

Nadal możemy ustawić go w konstruktorze, poprzez uruchamianie Pomocnicze ContextName.Context.tt T4 Szablon ten sposób:

<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext 
{ 
    public <#=code.Escape(container)#>() 
     : base("name=<#=container.Name#>") 
    { 
     Database.CommandTimeout = 180; 
<# 
if (!loader.IsLazyLoadingEnabled(container)) 
{ 
#> 
     this.Configuration.LazyLoadingEnabled = false; 
<# 
} 

Database.CommandTimeout = 180; jest zmiana acutaly.

Wygenerowany wyjście to:

public ContextName() : base("name=ContextName") 
{ 
    Database.CommandTimeout = 180; 
} 

Jeśli zmienisz bazę danych model ten szablon pozostaje, ale właściwie klasa zostanie zaktualizowany.

+0

Czy istnieje sposób określić limit czasu w szablonie przy użyciu pliku konfiguracyjnego.? – shas

+1

Nie jestem pewien, czy coś się w nim wbudowało (nie mogłem czegoś znaleźć). Ale zamiast kodowania twardego 180, można użyć ['System.Configuration.ConfigurationManager.AppSettings [" nazwa klucza "]'] (http://stackoverflow.com/questions/1189364/reading-settings-from-app-config-or- web-config-in-net) @shas –

+0

Tego właśnie szukałem. Dzięki za pomoc. – shas

Powiązane problemy