Tetapkan batas waktu basis data di Entity Framework


164

Perintah saya terus waktu habis, jadi saya perlu mengubah nilai batas waktu perintah default.

Saya sudah menemukan myDb.Database.Connection.ConnectionTimeout, tapi itu readonly.

Bagaimana saya bisa mengatur batas waktu perintah di Entity Framework 5 ?


20
FYI, Di EF6, Database.CommandTimeouttidak lagi hanya baca
itsho

2
@itsho yang dia bicarakan Database.Connection.ConnectionTimeout. Ngomong-ngomong, saya akan mengatakan bahwa itu Database.CommandTimeoutadalah hal yang benar dalam hal permintaan Anda habis waktu (pengecualian System.Data.Entity.Core.EntityCommandExecutionExceptionmengandung System.Data.SqlClient.SqlException: Timeout expired.).
David Ferenczy Rogožan


1
Saya berasumsi bahwa Anda sebenarnya tidak peduli dengan batas waktu SAMBUNGAN, tetapi Anda ingin menyesuaikan batas waktu PERINTAH.
Layak 7

Jawaban:


199

Coba ini pada konteks Anda:

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

Jika Anda ingin menentukan batas waktu dalam string koneksi, gunakan Connection Timeoutparameter seperti pada string koneksi berikut:

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

Sumber: Cara: Menentukan String Koneksi


1
Saya akan merekomendasikan menggunakan versi koneksi string seolah-olah Anda mencoba mengakses ObjectContextdi konstruktor ini kadang-kadang perintah konsol PowerShell / NuGet akan gagal secara melingkar .
Kevin Gorski

130
Koneksi Timeout dan CommandTimeout dan dua hal terpisah. Pengaturan string koneksi, Connection Timeout, tidak akan memengaruhi jumlah waktu perintah dijalankan (CommandTimeout).
Clay Lenhart

3
Masalah saya agak berbeda. Saya mendapat waktu tunggu selama migrasi. EF memiliki properti serupa yang akan ditetapkan untuk digunakan selama migrasi: msdn.microsoft.com/en-us/library/…
Karsten

2
Bergantung pada versi EF apa yang Anda gunakan, lihat jawaban ini untuk mengetahui tentang API yang berbeda dalam cara menentukan properti CommandTimeout.
Jim Aho

1
Tidak bekerja untuk saya (Koneksi vs Perintah tidak menjadi hal yang sama saya curigai). Posting ini diselesaikan meskipun stackoverflow.com/questions/6232633/entity-framework-timeouts
Jezbers

181

Kamu bisa memakai DbContext.Database.CommandTimeout = 180;

Ini sangat sederhana dan tidak diperlukan pemeran.


1
Sangat berguna bagi kita yang menggunakan Fluent APIformulir EF.
GoldBishop

20

Konteks parsial saya terlihat seperti:

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

Saya meninggalkan SetCommandTimeOutpublik jadi hanya rutinitas yang saya perlukan untuk waktu yang lama (lebih dari 5 menit) saya memodifikasi daripada timeout global.


9

Dalam kode konstruktor yang dihasilkan, ia harus memanggil OnContextCreated()

Saya menambahkan kelas parsial ini untuk memecahkan masalah:

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

8

Saya memperluas jawaban Ronnie dengan implementasi yang lancar sehingga Anda dapat menggunakannya seperti:

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

Untuk Pendekatan Database pertama:

Kita masih bisa mengaturnya dalam konstruktor, dengan menimpa Templat ContextName.Context.tt T4 dengan cara ini:

<#=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; adalah perubahan acutaly.

Output yang dihasilkan adalah ini:

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

Jika Anda mengubah Model Database Anda, template ini tetap, tetapi kelas yang sebenarnya akan diperbarui.


Apakah ada cara kita dapat menentukan batas waktu dalam Templat menggunakan beberapa file konfigurasi.?
shas

1
tidak yakin, jika ada sesuatu yang membangun (saya tidak dapat menemukan sesuatu). Tetapi alih-alih hardcoding 180, Anda dapat menggunakan System.Configuration.ConfigurationManager.AppSettings["keyname"]@shas
Christian Gollhardt

7

Sama seperti jawaban lain, tetapi sebagai metode ekstensi:

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

dan bagaimana saya memanggil metode ekstensi ini?
Wanderson López

1

Saya hanya mengalami masalah ini dan menyelesaikannya dengan memperbarui file konfigurasi aplikasi saya. Untuk koneksi yang dimaksud, tentukan "Connection Timeout = 60" (Saya menggunakan kerangka kerja versi 5.0.0.0)

Pengaturan ConnectionTimeout


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.