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 ?

James
sumber
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
2
Kemungkinan duplikat Timeout Kerangka Kerja Entitas
Tim Pohlmann
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

Leniel Maccaferri
sumber
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.

Vu Nguyen
sumber
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.

Erik Philips
sumber
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;
    }
}
Owen
sumber
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));
    } 
}
Timmerz
sumber
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.

Christian Gollhardt
sumber
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;
    }
}
Ronnie Overby
sumber
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

Andrew Burrow
sumber
0

Anda dapat menggunakan ini sederhana:
dbContext.Database.SetCommandTimeout(300);

Hassan Muhammad Saad
sumber