在ASP.NET中编写自己的提供程序类
注意:我不想编写自定义成员资格提供程序 我想编写自己的提供者类,这样我就可以在web.config中定义它,并像访问成员类一样访问它 下面是我的类的一个示例(它有许多其他静态方法): 用法:在ASP.NET中编写自己的提供程序类,asp.net,membership-provider,dataprovider,Asp.net,Membership Provider,Dataprovider,注意:我不想编写自定义成员资格提供程序 我想编写自己的提供者类,这样我就可以在web.config中定义它,并像访问成员类一样访问它 下面是我的类的一个示例(它有许多其他静态方法): 用法:MySqlHelper.ExecuteNonQuery(“从客户中选择*) 现在,正如您所看到的,我已经硬编码了connectionstring的名称,即“MyConnString”。我计划让它充满活力 因此,我想知道是否可以将其设置为静态内置成员类,在其中可以在web.config中定义connection
MySqlHelper.ExecuteNonQuery(“从客户中选择*)代码>
现在,正如您所看到的,我已经硬编码了connectionstring的名称,即“MyConnString”。我计划让它充满活力
因此,我想知道是否可以将其设置为静态内置成员类,在其中可以在web.config中定义connectionStringName。这样,该类就可以重复使用,而不必在web.config中将我的connectionstring命名为“MyConnString”
1:我不想在每个静态方法中都将connectionstring作为参数传递
2:我必须能够访问类似Membership.CreateUser的方法,即静态方法
我正在同时浏览网页,但任何输入/指导都会有所帮助
编辑:我已经更新了我的代码示例,以消除关于使用静态类的问题的一些混淆。下面是我发布的一篇文章来澄清这一点。很抱歉造成混淆。这是我在一些小项目中使用的SqlHelper
的完整代码。
但对于此类类,请小心使用静态。如果您将其用于Web项目,请记住,连接将在同一实例中为所有用户共享,这可能会导致严重问题
using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;
public class SqlHelper
{
private SqlConnection connection;
public SqlHelper()
{
connection = new SqlConnection();
}
public void OpenConnection()
{
// Updated code getting the ConnectionString without hard naming it.
// Yes, if you have more than 1 you'll have problems... But, how many times it happens?
if (WebConfigurationManager.ConnectionStrings.Length == 0)
throw new ArgumentNullException("You need to configure the ConnectionString on your Web.config.");
else
{
connection.ConnectionString = WebConfigurationManager.ConnectionStrings[0].ConnectionString;
connection.Open();
}
}
public void CloseConnection()
{
if (connection != null && connection.State != ConnectionState.Closed)
connection.Close();
}
public DataTable ExecuteToDataTable(string sql)
{
DataTable data;
SqlCommand command = null;
SqlDataAdapter adapter = null;
try
{
if (connection.State != ConnectionState.Open)
OpenConnection();
command = new SqlCommand(sql, connection);
adapter = new SqlDataAdapter(command);
retorno = new DataTable();
adapter.Fill(data);
}
finally
{
if (command != null)
command.Dispose();
if (adapter != null)
adapter.Dispose();
CloseConnection();
}
return data;
}
public int ExecuteNonQuery(string sql)
{
SqlCommand command = null;
try
{
if (connection.State != ConnectionState.Open)
OpenConnection();
command = new SqlCommand(sql, connection);
return command.ExecuteNonQuery();
}
finally
{
if (command != null)
command.Dispose();
CloseConnection();
}
}
public object ExecuteScalar(string sql)
{
SqlCommand command = null;
try
{
if (connection.State != ConnectionState.Open)
OpenConnection();
command = new SqlCommand(sql, connection);
return command.ExecuteScalar();
}
finally
{
if (command != null)
command.Dispose();
CloseConnection();
}
}
}
示例用法:
SqlHelper sql = new SqlHelper();
DataTable data = sql.ExecuteToDataTable("SELECT * FROM Customers");
int affected = sql.ExecuteNonQuery("INSERT Customers VALUES ('Test')");
但是如果你真的想要static
(如果你在一个单用户环境中),只需在所有方法上设置static
。这里是我在一些小项目中使用的SqlHelper
的完整代码。
但对于此类类,请小心使用静态。如果您将其用于Web项目,请记住,连接将在同一实例中为所有用户共享,这可能会导致严重问题
using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;
public class SqlHelper
{
private SqlConnection connection;
public SqlHelper()
{
connection = new SqlConnection();
}
public void OpenConnection()
{
// Updated code getting the ConnectionString without hard naming it.
// Yes, if you have more than 1 you'll have problems... But, how many times it happens?
if (WebConfigurationManager.ConnectionStrings.Length == 0)
throw new ArgumentNullException("You need to configure the ConnectionString on your Web.config.");
else
{
connection.ConnectionString = WebConfigurationManager.ConnectionStrings[0].ConnectionString;
connection.Open();
}
}
public void CloseConnection()
{
if (connection != null && connection.State != ConnectionState.Closed)
connection.Close();
}
public DataTable ExecuteToDataTable(string sql)
{
DataTable data;
SqlCommand command = null;
SqlDataAdapter adapter = null;
try
{
if (connection.State != ConnectionState.Open)
OpenConnection();
command = new SqlCommand(sql, connection);
adapter = new SqlDataAdapter(command);
retorno = new DataTable();
adapter.Fill(data);
}
finally
{
if (command != null)
command.Dispose();
if (adapter != null)
adapter.Dispose();
CloseConnection();
}
return data;
}
public int ExecuteNonQuery(string sql)
{
SqlCommand command = null;
try
{
if (connection.State != ConnectionState.Open)
OpenConnection();
command = new SqlCommand(sql, connection);
return command.ExecuteNonQuery();
}
finally
{
if (command != null)
command.Dispose();
CloseConnection();
}
}
public object ExecuteScalar(string sql)
{
SqlCommand command = null;
try
{
if (connection.State != ConnectionState.Open)
OpenConnection();
command = new SqlCommand(sql, connection);
return command.ExecuteScalar();
}
finally
{
if (command != null)
command.Dispose();
CloseConnection();
}
}
}
示例用法:
SqlHelper sql = new SqlHelper();
DataTable data = sql.ExecuteToDataTable("SELECT * FROM Customers");
int affected = sql.ExecuteNonQuery("INSERT Customers VALUES ('Test')");
但是如果你真的想要静态的
(如果你是在一个单用户环境中),只要把静态的
放在所有的方法上就行了。我能想到的唯一符合你提出的条件就是使用依赖注入,一个静态构造函数,然后注入一个类似于IConnectionStringProvider
的东西。这似乎是我能想到的最复杂的事情,所以你可能会喜欢它
编辑
在阅读您的评论之后,您似乎只希望能够引用任何连接字符串,但每个应用程序只能引用一个连接字符串。我想说的是,只需向appSettings
添加一个名为MySqlProviderConnection
的元素,该值是要使用的连接字符串的名称
然后在助手中,检查appsetting是否存在,获取其值,并将其传递给ConfigurationManager.connectionString
调用。这样,您的提供者就可以使用您想要的任何连接,而无需更改任何代码。我能想到的唯一符合您提出的条件是使用依赖项注入,一个静态构造函数,并注入类似于IConnectionStringProvider的内容。这似乎是我能想到的最复杂的事情,所以你可能会喜欢它
编辑
在阅读您的评论之后,您似乎只希望能够引用任何连接字符串,但每个应用程序只能引用一个连接字符串。我想说的是,只需向appSettings
添加一个名为MySqlProviderConnection
的元素,该值是要使用的连接字符串的名称
然后在助手中,检查appsetting是否存在,获取其值,并将其传递给ConfigurationManager.connectionString
调用。这样,您的提供商就可以使用您想要的任何连接,而无需更改任何代码。我通常不建议跨多个请求共享一个SqlConnection实例。即使启用,也可能会遇到性能问题。我认为,当您的连接接收到非读取命令时,连接缓冲区将暂停所有当前读取,直到写入完成。你唯一真正节省的是建立连接所需的时间
SqlConnections非常有用,因此您可以配置提供程序,使其具有可用于请求客户端的最小/最大实例数。请记住,这也是由您连接到的任何数据库控制的;假设您正在连接到SQL Server实例,SQL Server有其自己的“允许的最大连接数”设置
我建议让您的公共成员接受命令字符串或命令参数,而不是让客户端决定何时打开/关闭共享SqlConnection实例。然后,与示例所建议的类似,从池中打开连接并执行命令
public IEnumerable<SqlResults> ExecuteStoredProcedure(string procedure, params SqlParameter[] parameters) {
using(SqlConnection connection = new SqlConnection(MyConnectionStringProperty)) {
try {
connection.Open();
using(SqlCommand command = new SqlCommand(procedure, connection)) {
command.CommandType = CommandType.StoredProcedure;
if(parameters != null) {
command.Parameters.AddRange(parameters);
}
// yield return to handle whatever results from proc execution
// can also consider expanding to support reader.NextResult()
using(SqlDataReader reader = command.ExecuteReader()) {
yield return new SqlResults {
Reader = reader;
};
}
}
}
finally {
if(connection.State != ConnectionState.Closed) {
connection.Close();
}
}
}
}
在处理结果时不关闭连接。如果您在示例中注意到,我们为SqlClient
对象使用了using
语句。这种方法允许结果集处理与MySqlHelper
分离,因为提供者类将处理可能重复的SQL提供代码,将结果处理委托给调用者,然后继续执行它必须执行的操作(即关闭连接)
至于IoC/DI,我个人使用。可以将依赖项对象作为属性或构造参数注入。将控制反转容器注册为依赖项资源管理器将允许您(除其他外)在请求资源类型时返回相同的对象。基本上,对于每个需要使用MySqlHelper
的调用方类,当调用方类被实例化或调用方类引用其公共MySqlHelper
属性时,可以插入相同的实例。一、 就个人而言,尽可能地选择构造函数注入。另外,当我说注入时,我的意思是你不必担心设置