entity framework – 当前命令超时值是什么

我正在使用Entity Framework 5,我希望知道命令超时值。

为此,我将dbContext对象转换为ObjectContext,然后访问CommandTimeout属性。

int ? currentCommandTimeout = ((IObjectContextAdapter)dbContext).ObjectContext.CommandTimeout; 

此属性的当前值为null,这意味着当前命令超时是基础提供程序的默认值。

  1. 谁是底层提供者?
  2. 在这种情况下,如何读取(通过EF代码)当前命令超时值?

MSDN ObjectContext CommandTimeout属性引用

编辑:感谢您解释如何设置命令超时并在文档中查找默认命令超时值。 但问题仍未解决。 如果可能,如何在默认情况下通过EF读取命令超时值。

来自MSDN,

  • CommandTimeout属性获取或设置所有对象上下文操作的超时值(以秒为单位)。
  • null值表示将使用基础提供程序的默认值。

因此,如果您没有通过代码显式设置它或在连接字符串中传递它(在MySQL中),那么它是您的提供者的默认值。

如果要查看CommandTimeout的非null值,则需要在connectionString中传递它或通过代码设置它。

谁是底层提供者?

底层提供程序是您在connectionstring中作为providerName传递的providerName

     

这里, System.Data.ProviderName是您的底层提供者。

如果您使用的是MySql或MS Sql,根据MySql文档和MSDN ,

  • 默认值为30 secs
  • 值0表示无限期等待,应该避免。

    注意 :

对于MySQL数据库提供程序,可以使用connectionstring属性Default Command Timeout更改Default Command Timeout

如果您使用的是SQLServer,则默认命令超时为30秒。

SqlCommand.CommandTimeout属性

  1. 谁是底层提供者?

要远程连接到任何数据库并触发SQL查询,您需要一个机制或中介(您可以说),它理解在触发查询时要采取的各种操作的通信语义,例如创建命令,建立连接,处理连接超时,重试等

所有这些职责由您尝试连接的数据库的提供程序负责。 这些提供程序将具有与您连接的环境(C#,Java,Python,Perl等)不同的实现和类。 因此,要连接到MySQL数据库,您将拥有适用于java,.net或python编程世界的不同提供程序。

  1. 在这种情况下,如何读取(通过EF代码)当前命令超时值?

不。 这是不可能的。 如果仔细查看dbContext.Database.CommandTimeout属性,它的类型是int? 。 因此,将此属性保持为可为空的int的后勤仅表示默认值(为null)。 在C#代码中设置显式值之前,entity framework(EF)不会公开任何内容。 我对以下数据库进行了validation

  • MySQL的
  • SQL Server

在这两种情况下,我都看到在创建DB上下文对象后,命令超时属性设置为null ,这表明它使用的是基础提供程序提供的默认值。

但是,如果您通过dbContext.Database.CommandTimeout属性在C#代码中将其设置为非空值,那么您当然可以再次读取它,因为它是命令对象上的get-set属性。 它将始终显示在代码中明确设置的新值。

如果将其设置为null则EF将再次使用基础提供程序的默认超时。

使用提供者类代替EF层 :如果您不使用entity framework的ORM层并使用提供者的核心类,那么您当然可以在初始化本身看到默认的超时值。 就像我在下面提到的MySQL数据库的代码运行时,默认命令超时值已经在连接字符串本身中设置,然后你会看到40。

 private static void TestingCommandTimeOutInMySql() { string connetionString = "Server=localhost;Database=sakila;Uid=root;Pwd=Passw0rd;default command timeout=40;"; MySqlConnection con = new MySqlConnection(connetionString); try { cnn.Open(); Console.WriteLine("Connection Open ! "); MySqlCommand cmd = new MySqlCommand("select * from actor", con); var timeoutValue = cmd.CommandTimeout; //shows 40 con.Close(); } catch (Exception ex) { Console.WriteLine("Can not open connection ! "); } } 

如果未在连接字符串中设置任何内容,则MySQL的默认值为30。 这里的CommandTimeoutint ,不是int? 。 所以EF肯定会应用一些智能,同时暴露提供者类的这个属性,这些属性最终由EF通过dbContext.Database.CommandTimeout 。 EF只是这些提供程序类的包装器,具有一些额外的智能。

关于连接蜇的其他细节很少:

对于SQL Server提供程序: Microsoft SQL Server连接字符串格式不提供任何属性,您可以在其帮助下设置自定义命令执行超时。 因此,在SQL Server提供程序初始化期间设置值是不可能的。 尽管在实例化/初始化之后,您仍然可以更改C#代码中的值。 你可以在这里看到更多细节。

对于MySQL提供程序:我的SQL连接字符串格式支持显式设置默认命令超时。 你可以在这里找到详细信息。 您可以在MySQL连接字符串中提及自定义默认命令超时值,如下所示 –

 default command timeout=200; 

这应该工作

 var ctx = new DbContext(); ctx.Database.CommandTimeout = 120; 

我就是这样做的。

 ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext int commandTimeout = objectContext.CommandTimeout ?? objectContext.Connection.CreateCommand().CommandTimeout;