- 谁是底层提供者?
要远程连接到任何数据库并触发 SQL 查询,您需要一种机制或中介(可以说),它了解在触发查询时要采取的各种操作的通信语义,例如创建命令、建立连接、处理连接超时,重试等
所有这些责任都由您尝试连接的数据库的提供者负责。这些提供程序将在您连接的环境(C#、Java、Python、Perl 等)中具有不同的实现和类。因此,要连接到 MySQL 数据库,您将拥有不同的 java、.net 或 python 编程世界提供程序。
- 在这种情况下,如何读取(通过 EF 代码)当前命令超时值?
没有。这是不可能的。如果您仔细查看该dbContext.Database.CommandTimeout
属性,它是类型int?
。因此,将此属性保持为可空 int 的逻辑只是表示默认值(为空)。在您在 C# 代码中设置显式值之前,实体框架 (EF) 不会公开任何内容。我针对以下数据库验证了这一点
在这两种情况下,我看到在创建 DB 上下文对象后,命令超时属性设置为null
表明它正在使用底层提供程序提供的默认值。
但是,是的,如果您在 C# 代码中通过属性将其设置为非空值dbContext.Database.CommandTimeout
,那么您当然可以再次读取它,因为它是命令对象上的 get-set 属性。它总是会显示在代码中明确设置的新值。
如果您将其设置回,null
则 EF 将再次开始使用底层提供程序的默认超时。
使用提供程序类代替 EF 层:如果您不使用实体框架的 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。这里CommandTimeout
是int
,不是int?
。所以 EF 在暴露提供者类的这个属性时确实应用了一些智能,这些属性最终由 EF 通过dbContext.Database.CommandTimeout
. EF 只是这些提供程序类的包装器,具有一些额外的智能。
关于连接线的一些额外细节:
对于 SQL Server 提供程序:
Microsoft SQL Server 连接字符串格式不提供任何可以帮助您设置自定义命令执行超时的属性。因此,根本不可能在 SQL Server 提供程序的初始化期间设置一个值。尽管在实例化/初始化之后,您始终可以更改 C# 代码中的值。您可以在此处查看更多详细信息。
对于 MySQL Provider:
My SQL 连接字符串格式支持显式设置默认命令超时。您可以在此处找到详细信息。您可以像这样在 MySQL 连接字符串中提及自定义默认命令超时值 -
default command timeout=200;