Entity Framework'te veritabanı zaman aşımını ayarlama


164

Komutum zaman aşımına uğradı, bu yüzden varsayılan komut zaman aşımı değerini değiştirmem gerekiyor.

Buldum myDb.Database.Connection.ConnectionTimeout, ama öyle readonly.

Entity Framework 5'te komut zaman aşımını nasıl ayarlayabilirim ?


20
FYI, EF6'da Database.CommandTimeoutartık salt okunur değil
itsho

2
@itsho bahsediyordu Database.Connection.ConnectionTimeout. Neyse, ben Database.CommandTimeoutsorgu zaman aşımı (istisna System.Data.Entity.Core.EntityCommandExecutionExceptioniçeren System.Data.SqlClient.SqlException: Timeout expired.) durumda doğru şey olduğunu söyleyebilirim .
David Ferenczy Rogožan


1
Aslında BAĞLANTI zaman aşımı ile ilgilenmediğinizi, bunun yerine KOMUT zaman aşımını ayarlamak istediğinizi varsayalım.
Worthy7

Yanıtlar:


199

Bunu bağlamınızda deneyin:

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

Bağlantı dizesindeki zaman aşımını tanımlamak istiyorsanız Connection Timeout, aşağıdaki bağlantı dizesindeki gibi parametreyi kullanın :

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

Kaynak: Nasıl yapılır: Bağlantı Dizesini Tanımlama


1
ObjectContextBu yapıcıda bazen PowerShell / NuGet konsol komutlarına erişmeye çalıştığınız gibi bağlantı dizesi sürümünü kullanmanızı öneririm dairesel bir şekilde başarısız olur .
Kevin Gorski

130
Bağlantı Zaman Aşımı ve CommandTimeout ve iki ayrı şey. Bağlantı dizesi ayarı, Bağlantı Zaman Aşımı, komutun çalışma süresini etkilemez (CommandTimeout).
Clay Lenhart

3
Benim sorunum biraz farklıydı. Taşıma sırasında zaman aşımı oldu. EF, taşıma sırasında kullanmak için benzer bir özelliğe sahiptir: msdn.microsoft.com/en-us/library/…
Karsten

2
Hangi EF sürümünü kullandığınıza bağlı olarak , farklı API'ler hakkında CommandTimeout özelliğinin nasıl belirtileceği konusunda bir fikir edinmek için bu cevaba bakın .
Jim Aho

1
Benim için çalışmıyor (Bağlantı vs Komut şüphelendiğim aynı şey olmamak). Bu yazı stackoverflow.com/questions/6232633/entity-framework-timeouts
Jezbers

181

Kullanabilirsiniz DbContext.Database.CommandTimeout = 180;

Oldukça basit ve döküm gerektirmez.


1
Fluent APIEF formunu kullanan bizim için çok faydalı .
GoldBishop

20

Kısmi bağlamım şöyle:

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;
    }
}

Ben SetCommandTimeOutgenel bir zaman aşımı yerine ben sadece uzun bir süre (5 dakikadan fazla) alması gereken rutinleri halka açık bıraktım .


9

Oluşturulan kurucu kodunda OnContextCreated()

Sorunu çözmek için bu kısmi sınıfı ekledim:

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

8

Ronnie'nin cevabını akıcı bir uygulama ile genişlettim, böylece şöyle kullanabilirsiniz:

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));
    } 
}

8

Önce Veritabanı Yaklaşımı için:

ContextName.Context.tt T4 Şablonunu şu şekilde geçersiz kılarak bir kurucuda ayarlayabiliriz :

<#=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; akut değişimdir.

Üretilen çıktı şudur:

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

Veritabanı Modelinizi değiştirirseniz, bu şablon kalır, ancak gerçek sınıf güncellenir.


Bazı yapılandırma dosyasını kullanarak Şablon'da zaman aşımı süresini belirlememizin bir yolu var mı?
shas

1
emin değilim, eğer inşa edilmiş bir şey varsa (bir şey bulamadım). Ancak hardcoding 180 yerine, System.Configuration.ConfigurationManager.AppSettings["keyname"]@shas
Christian Gollhardt

7

Diğer yanıtlarla aynı, ancak bir uzantı yöntemi olarak:

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

ve bu uzantı yöntemini nasıl adlandırırım?
Wanderson López

1

Bu sorunla karşılaştım ve uygulama yapılandırma dosyamı güncelleyerek çözdüm. Söz konusu bağlantı için "Bağlantı Zaman Aşımı = 60" belirtin (Varlık çerçevesi sürümü 5.0.0.0 kullanıyorum)

ConnectionTimeout Ayarı


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.