【问题标题】:Set database timeout in Entity Framework在实体框架中设置数据库超时
【发布时间】:2012-09-29 03:09:25
【问题描述】:

我的命令一直超时,所以我需要更改默认的命令超时值。

我找到了myDb.Database.Connection.ConnectionTimeout,但它是readonly

如何在 Entity Framework 5 中设置命令超时?

【问题讨论】:

  • 仅供参考,在 EF6 上,Database.CommandTimeout 不再是只读的
  • @itsho 他说的是Database.Connection.ConnectionTimeout。无论如何,如果您的查询超时,我会说Database.CommandTimeout 是正确的(例外System.Data.Entity.Core.EntityCommandExecutionException 包含System.Data.SqlClient.SqlException: Timeout expired.)。
  • Entity Framework Timeouts的可能重复
  • 我假设您实际上并不关心 CONNECTION 超时,而是您想调整 COMMAND 超时。

标签: c# .net asp.net-mvc entity-framework connection-timeout


【解决方案1】:

在你的上下文中试试这个:

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

如果要在连接字符串中定义超时,请使用Connection Timeout 参数,如以下连接字符串:

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

来源:How to: Define the Connection String

【讨论】:

【解决方案2】:

我的部分上下文如下所示:

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

我离开了SetCommandTimeOut public,所以我只修改了我需要花费很长时间(超过 5 分钟)的例程,而不是全局超时。

【讨论】:

    【解决方案3】:

    与其他答案相同,但作为扩展方法:

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

    【讨论】:

    • 我该如何调用这个扩展方法?
    【解决方案4】:

    我用流畅的实现扩展了 Ronnie 的答案,因此您可以像这样使用它:

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

    【讨论】:

      【解决方案5】:

      在生成的构造函数代码中应该调用OnContextCreated()

      我添加了这个部分类来解决问题:

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

      【讨论】:

        【解决方案6】:

        您可以使用DbContext.Database.CommandTimeout = 180; // seconds

        这很简单,不需要演员表。

        【讨论】:

        • 对使用Fluent API EF 形式的我们非常有用。
        【解决方案7】:

        对于数据库优先方法:

        我们仍然可以在构造函数中设置它,通过这种方式覆盖 ContextName.Context.tt T4 模板:

        <#=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; 是真正的变化。

        生成的输出是这样的:

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

        如果您更改数据库模型,此模板将保留,但实际类将更新。

        【讨论】:

        【解决方案8】:

        你可以使用这个简单的 :
        dbContext.Database.SetCommandTimeout(300);

        【讨论】:

          【解决方案9】:

          我刚刚遇到了这个问题,并通过更新我的应用程序配置文件解决了这个问题。对于有问题的连接,指定“Connection Timeout=60”(我使用的是实体框架版本 5.0.0.0)

          ConnectionTimeout Setting

          【讨论】:

            【解决方案10】:

            您应该在 web 配置中的 Connection String 标记中进行更改,并让 EntityFrameWork 在其构造函数中从中读取。

            1. 将此术语添加到 web.config 连接字符串: 连接超时=300;

            2. 在构造函数中添加如下代码:

              Database.CommandTimeout = 数据库.Connection.ConnectionTimeout;

            通过这种方法,您将使用户能够控制超时,而无需为他进行新的发布。

            【讨论】:

            • 如前所述:连接超时!= 命令超时。命令超时在这里很重要。
            • 这种方法是从连接字符串中动态读取,而不是单独设置。
            • 那个细节没有让我看到,这立即表明了这种黑客行为的问题。这是完全出乎意料的,永远不应该这样做。
            • 黑客检查应该从其他地方完成,我认为命令的命令超时时间应该足够长以执行长查询或 SQL 命令。因此,网站管理员应该能够根据自己的需要控制此时间段,而无需仅仅更改命令超时时间段而获得新的发布。
            • 不要滥用连接字符串中的 Connection Timeout 设置!下一个应用程序管理器会将其设置为其他值,而不会意识到它的含义。而且,请记住,它设置连接超时(显然)。如果由于某些意外情况碰巧连接不可用,您不希望人们等待 5 分钟。
            猜你喜欢
            • 1970-01-01
            • 2012-07-29
            • 1970-01-01
            • 2013-08-26
            • 1970-01-01
            • 1970-01-01
            • 2012-05-29
            • 1970-01-01
            • 2015-12-01
            相关资源
            最近更新 更多