我有一个内部构造和使用SqlConnection类的第三方库.我可以从班级继承,但它有很多重载,到目前为止我一直找不到合适的.我想要的是使用正在使用的连接字符串的参数.
有没有办法让我在.NET库核心本身设置一个断点?特别是在SqlConnection类的构造函数中,以便我可以查看堆栈跟踪并查看它实际构建的位置?
除此之外,还有其他方法可以做到这一点吗?
具体来说,我想要做的是使用Application Name参数,以便在查看连接时更容易在服务器上识别我们的应用程序.
编辑:嗯,似乎我需要更多的帮助.我想我已经启用了与符号服务器支持相关的所有内容,并且我注意到我配置的目录已经填满了包含.pdb文件的目录.但是,我无法获得SqlConnection类的实际源代码.
是否有一些明确的指导如何成功地做到这一点?
我目前正在使用ASP.NET创建一个Webportal,它在很大程度上依赖于数据库的使用.基本上,来自任何用户的每个(几乎每个:P)GET查询都将导致从Web服务器查询数据库.
现在,我对此非常陌生,而且我非常关注性能.由于我在这方面缺乏经验,我真的不知道会发生什么.
我的问题是,使用ADO.NET,只是将静态连接从Web服务器打开到数据库,然后在每次查询数据库之前检查此连接服务器端的完整性,这是一个更明智的选择吗? - 或者,我最好在每次查询之前打开连接然后关闭它?
在我的脑海中,第一个选项会更好,因为您在每个查询之前节省了时间握手等,并且您在数据库和服务器端都节省了内存,因为您只有一个连接,但这种方法是否有任何缺陷?2个查询是否可以同时发送可能会破坏彼此的完整性或混合返回的数据集?
我已经尝试在这里和网上搜索,找到一些关于此的最佳实践,但没有运气.我得到的最近的是:保持数据库连接打开很长时间是安全的,但这似乎更适合于你有多个数据库用户的分布式系统,而我只有我的网络服务器..
例如,我需要使用SQLDataAdapter的Fill()方法填充大量DataTable:
DataAdapter1.Fill(DataTable1);
DataAdapter2.Fill(DataTable2);
DataAdapter3.Fill(DataTable3);
DataAdapter4.Fill(DataTable4);
DataAdapter5.Fill(DataTable5);
....
....
Run Code Online (Sandbox Code Playgroud)
即使所有的dataadapter对象都使用相同的SQLConnection,每个Fill方法都会打开和关闭连接,除非在方法调用之前连接状态已经打开.
我想知道的是,如何不必要地打开和关闭SQLConnections会影响应用程序的性能.需要扩展多少才能看到此问题的不良影响(100,000个并发用户?).在中型网站(每天50000个用户)中,是否值得烦恼并搜索所有Fill()调用,将它们保存在代码中并在任何Fill()调用之前打开连接并在之后关闭?
using (SqlConnection con = new SqlConnection())
{
try
{
con.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
这很好用.但我想知道我们可以处理异常而不使用try catch某些东西 if else吗?或者使用它是否具有变化性try catch
我想在类中重复使用相同的 SQLConnection 和不同的方法。我现在正在做的(仅测试)是在构造函数中创建和打开一个连接:
SQLConnection Connection;
Constructor(string connection_string)
{
this.Connection = new SqlConnection(connection_string);
this.Connection.Open();
}
Run Code Online (Sandbox Code Playgroud)
然后我在方法内部使用“this.Connection”,最后在不再需要对象时使用 this.Connection.Close() 和 Dispose() 。据我所知,在这样的每个方法中使用 'using' 会更干净(构造函数只会设置 connection_string):
using (SqlConnection connection = new SqlConnection(connection_string)) {
connection.Open(); ...
}
Run Code Online (Sandbox Code Playgroud)
由于连接池,实际上只使用了一个连接,尽管上面的“使用”行被放置在多个方法中(例如,当它们一个接一个地被调用时),对吗?但是,这不会创建许多只需要一个的 SQLConnection 实例吗?例如:
MyClass obj(some_string);
obj.Method1(); // calls 'using SqlConnection connection = new SqlConnection'
obj.Method2(); // calls 'using SqlConnection connection = new SqlConnection'
obj.Method3(); // calls 'using SqlConnection connection = new SqlConnection'
Run Code Online (Sandbox Code Playgroud)
那么共享 SQLConnection 的正确、最佳方式是什么?
除了旧的已知事实,即connection.Close()vs connection.Dispose()是相同的 - 除了在关闭的连接上运行时,Close()在已处理的连接上运行引发异常Close()- 是的 - 我还有一个问题:
假设连接池已打开,(默认) - 为什么记住连接状态很重要?
我在这里读到了这个问题,它表明 - 避免打开和关闭连接可以节省性能.
这似乎是逻辑,但问题是连接永远不会被关闭!它只标记为关闭.
即使我在using范围内使用它- dispose只是关闭连接并将其放回池中.
即使我想要,我也不能让它开放(因为我希望其他人使用它).所以我不得不关闭/处理它.
看看Dapper 也实现了这种行为:
public static async Task<IEnumerable<T>> QueryAsync<T>(this...)
{
//...
bool wasClosed = cnn.State == ConnectionState.Closed;
using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
{
try
{
if (wasClosed) await ((DbConnection)cnn).OpenAsync()...
//...
}
finally
{
if (wasClosed) cnn.Close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,"记忆"在这里实现.
NB,我已经问马克有关相关主题是-为什么短小精悍的样品中,他同时使用 …
我正在尝试创建一个临时数据库以在 Xunit 中进行集成测试,但是当我尝试删除临时数据库时,出现错误:
无法删除数据库“TempDatabase_[numbers]”,因为它当前正在使用中。
简单地关闭和处理命令和连接似乎并不能切断它。
这是我失败的测试的精简版:
using System;
using System.Data.SqlClient;
using Xunit;
namespace Test
{
public class Test_Raw_Spec
{
[Fact]
public void PerformWorkInTemporaryDatabase()
{
string connectionStringTemplate = "Data Source=SQLEXPRESS;Initial Catalog={0};Integrated Security=SSPI;Connection Timeout=10";
int dbNum = (new Random()).Next() % 1000000;
int tblNum = (new Random()).Next() % 1000000;
string nameTempDb = $"TempDatabase_{dbNum}";
string nameTempTable = $"TempTable_{tblNum}";
var sqlConnection1 = new SqlConnection(string.Format(connectionStringTemplate, "master"));
var sqlCommand1 = new SqlCommand($"CREATE DATABASE {nameTempDb}", sqlConnection1);
sqlConnection1.Open();
sqlCommand1.ExecuteNonQuery();
sqlCommand1.Dispose();
sqlConnection1.Close();
sqlConnection1.Dispose();
var sqlConnection2 = new SqlConnection(string.Format(connectionStringTemplate, nameTempDb));
var …Run Code Online (Sandbox Code Playgroud) 这有点奇怪,但我想检查我的数据库的连接是否已经打开?我该如何检查?如果打开我希望能够直接使用它而不通过所有声明:
sqlconnection conn = new sqlconnection("string ...");
Run Code Online (Sandbox Code Playgroud)
可以这样做吗?我也知道连接字符串和连接名称.我想先检查此连接是否可用,然后继续.
c# sql-server database-connection sqlconnection visual-studio-2010
我最近才了解到这种连接池机制,发现我编写的SQL连接错误.我过去常常维护一个全局SQL连接,所有SqlCommands这些连接都将执行.
所以我现在正在对现有代码进行大规模更改.有不少于260个SqlCommands引用SqlConnection我正在忙着包装的全局
using (SqlConnection sqlConnection = new SqlConnection(globally_stored_connection_string))
{
sqlConnection.Open();
// SqlCommand comes here
}
Run Code Online (Sandbox Code Playgroud)
我认为这仍然是我必须做的一个范式转换,这个关闭连接的业务只是在不久之后打开一个新的,信任连接池来处理开销.考虑到这一点,我现在需要决定如何SqlCommands在循环内多次调用包装.非常感谢您对以下哪些代码段的首选(当然,除此之外还有更多内容,SqlCommands但这些是用来说明问题的简单示例).
选项A:
using (SqlConnection sqlConnection = new SqlConnection(connection_string))
{
foreach(int number in numberList)
{
using (SqlCommand sqlCommand = new SqlCommand("SQL code here using number from foreach loop", sqlConnection))
{
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
}
}
}
Run Code Online (Sandbox Code Playgroud)
选项B:
foreach (int number in numberList)
{
using (SqlConnection sqlConnection = new SqlConnection(connection_string))
{
sqlConnection.Open();
using (SqlCommand sqlCommand = new SqlCommand("SQL …Run Code Online (Sandbox Code Playgroud) 我正在使用Visual Studio的代码分析工具,它给我的一个警告是"不要多次处置对象:对象'conn'可以在方法'CycleMessages.discernScan_Reprint()'中多次处理."以避免生成System.OjectDisposedEx你不应该在一个对象上多次调用Dispose.行:61
private void discernScan_Reprint()
{
try
{
DataTable dt = new DataTable();
SqlConnection conn = new SqlConnection("my constring");
using (conn)
{
SqlCommand cmd = new SqlCommand("usp_myproc", conn);
cmd.CommandType = CommandType.StoredProcedure;
using(cmd)
{
cmd.Parameters.Add(new SqlParameter("@param", param));
conn.Open();
SqlDataReader dr = cmd.ExecuteReader();
dt.Load(dr);
conn.Close(); // this is line 61
}
}
switch(dt.Rows.Count)
{
default:
throw new Exception("message");
case 1:
//do Stuff
case 0:
//do stuff
break;
}
}
catch (Exception ex) {throw;}
}
Run Code Online (Sandbox Code Playgroud)
我没有处理conn(显式通过conn.Dispose();),我只是关闭它并允许使用封装来conn对象 - 我知道我可以允许它通过处理关闭,但为什么是它说我要两次处理它?如果有的话它应该警告我说"你不需要终止对将被处置的物体的连接"或类似的东西.我错过了什么吗?
编辑:从关闭的ref链接...
Close方法回滚所有挂起的事务.然后,它会释放与连接池的连接,或者在禁用连接池时关闭连接.
和
如果SqlConnection超出范围,则不会关闭.因此,您必须通过调用Close或Dispose显式关闭连接.关闭和处置在功能上是等效的.如果连接池值Pooling设置为true或yes,则将基础连接返回到连接池.另一方面,如果Pooling设置为false或no,则关闭与服务器的基础连接.
我知道功能上的Close()与dispose相同,但这不符合我的理解.当我关闭物体时它没有被丢弃.它被关闭或返回到连接池,处理(再次从我的理解)内部调用close()方法 …
sqlconnection ×10
c# ×7
.net ×4
sql-server ×3
ado.net ×1
breakpoints ×1
dapper ×1
database ×1
dispose ×1
exception ×1
fill ×1
runtime ×1
sql ×1
sqlcommand ×1
try-catch ×1
using ×1
web ×1