转载 http://www.codeproject.com/cs/database/SqlWrapper.asp
源代码本地下载:
使用SQLWrapper库,你可以写非常少的代码来创建你的数据访问类.
简介
你曾经在你的项目中创建数据访问层吗?你很可能创建了一个类或者一些类,他们包含几个方法,调用了存储过程或者执行一个SQL语句.如果数据库包含很多表,这是个很烦人的工作过程.最糟糕的是,这个方法要很多的同样的步骤(创建一个命令对象,填充它的属性,执行,然后返回结果).并且很少包含其他的逻辑.你有两个方法:手工写这些代码,或者(自动)生成他们.这两个方法,你会有很多源代码.
以前我在用这两个方法时,我就感觉在哪里有更容易的方法.AutoSprocTool给我一个开发SqlWrapper库的想法.
一个简单的例子
让我们写两个类,他们和Northwind数据库一起工作.一个类Orders1使用通常的方法.
差异是显而易见的.Orders2 包含了很少的代码但是他们使用起来差不多相同,仅仅是创建的方法不同.
public class Orders1


{
private SqlConnection m_connection = null;

public SqlConnection Connection

{

get
{return m_connection;}

set
{m_connection = value;}
}

public DataSet CustOrdersDetail(int OrderID)

{
SqlCommand cmd = new SqlCommand("CustOrdersDetail", m_connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@OrderID", SqlDbType.Int);
cmd.Parameters["@OrderID"].Value = OrderID;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}

public int CountByEmployee(int EmployeeID)

{
SqlCommand cmd = new SqlCommand(
"select count(*) from Orders where EmployeeID=@EmployeeID",
m_connection);
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("@EmployeeID", SqlDbType.Int);
cmd.Parameters["@EmployeeID"].Value = EmployeeID;
int count = (int)cmd.ExecuteScalar();
return count;
}
}

另一个使用SqlWrapper,
public abstract class Orders2 : SqlWrapperBase


{
public abstract DataSet CustOrdersDetail(int OrderID);

[SWCommand("select count(*) from Orders where EmployeeID=@EmployeeID")]
public abstract int CountByEmployee(int EmployeeID);
}

现在让我们看看如何使用这些类.
SqlConnection cnn = new SqlConnection(
ConfigurationSettings.AppSettings["ConnectionString"]);
cnn.Open();

// working with the ordinary class
Orders1 orders1 = new Orders1();
orders1.Connection = cnn;
DataSet ds1 = orders1.CustOrdersDetail(10248);
int count1 = orders1.CountByEmployee(6);

// working with the wrapped class
Orders2 orders2 = (Orders2)WrapFactory.Create(typeof(Orders2));
orders2.Connection = cnn;
DataSet ds2 = orders2.CustOrdersDetail(10248);
int count2 = orders2.CountByEmployee(6);


SqlWarpper如何工作
为了创建一个包装类,你要从SqlWrapperBase继承,并且定义抽象方法,使用自定义属性定义要执行什么,如何获得和获得什么结果.如果没有指定方法属性,那么方法的名称将被用做存储过程名称.你也可以定义任意数量的具体方法,如果你要在执行sql语句之外,还有一些更多的逻辑.然后,你可以通过调用WrapFactory.Create()方法,创建定义类的一个对象.这个方法使用System.Reflection.Emit 命名空间的类,为抽象方法添加执行.例如,下面的方法:
[SWCommand("select count(*) from Orders where EmployeeID=@EmployeeID")]
public abstract int CountByEmployee(int EmployeeID);

将被执行为:
[SWCommand("select count(*) from Orders where EmployeeID=@EmployeeID")]
public int CountByEmployee(int EmployeeID)


{
MethodInfo method = (MethodInfo)MethodBase.GetCurrentMethod();
object[] values = new object[1];
values[0] = EmployeeID;
object obj = SWExecutor.ExecuteMethodAndGetResult(
m_connection,
m_transaction,
method,
values,
m_autoCloseConnection);

return (int)obj;
}


SWExecutor.ExecuteMethodAndGetResult() 方法执行了主要的工作.它创建了SqlCommand和返回了执行的结果. 为了这个用途,变量method提供了下面的信息:
command text (命令)
command type (命令类型)
execution method (执行的方法名称)
parameter names (参数名称)
parameter data types (参数类型)
parameter directions (参数方向)
parameter sizes, scales and precisions (参数的大小,范围,精度)
behavior in case null or DBNull is returned instead of a scalar value
如果没有返回一个精度值,而是返回了空或者DBNull时的行为.
behavior in case DBNull value must be passed to a parameter
如果必须传递一个空值作为参数时的行为.
所有的这些信息都将通过方法签名提供,其他可选的通过方法属性和参数属性.
下面的图显示了SqlWrapper类直接的联系
SqlWrapperBase
SqlWrapperBase类是所有的包装类的基本类,它包含了下面的属性:
Connection 属性
Transaction 属性
AutoCloseConnection 属性.如果为真,那么连接在每次的命令执行完毕就会自动关闭.
你可以在你的包装类中使用上面的属性,因为他们是protected.
SWCommandAttribute
这是一个可选的方法属性,包含了下面的属性.
CommandType可以是下面的值:SWCommandType.Text,SWCommandType.StoreProcedure和SWCommandType.InsertUpdate.这几个值类似于System.Data.CommandType枚举的值. SWCommandType.InsertUpdate 将在以后讲述.默认值是SWCommandType.Text.
CommandText 包含了一个命令文本.这依赖于CommandType属性值.
ReturnIfNull包含了一个值,如果执行了一个命令返回了空,那么将返回此值.
MissingSchemaAction是一个值,SqlDataAdapter.MissingShemaAction.默认是Add.
除了CommandText属性以外都是可选的属性.
重要:如果这个属性省略了,那么方法名称将被用做CommandText属性,CommandType属性将等于SWCommandTYpe.StoreProcedure.
SWParameterAttribute
这是一个可选的参数属性,包含下列属性:
Name:包含了参数名称,如果省略,使用方法参数名称
SqlDbType,包含了值的类型,对应了SqlParameter.SqlDbType属性.
Size 包含了命令参数的大小,对应了SqlParameter.Size属性.
Precision 包含了参数的精度.对应了SqlParameter.Presision
Scale 包含了参数的小数位数.对应了SqlParameter.Scale.
TreatAsNull 包含了被翻译成DBNull的值.在数字参数时很有用.
ParameterType 包含了下列值:SWParameterType.Default, SWParameterType.SPReturnValue, SWParameterType.Key 和 SWParameterType.Identity.默认值是SWParameterType.Default.
所有的属性都是可选的.
当ParameterType属性值是SWParameterType.SPReturnValue 时,即这个方法参数包含一个存储过程返回值,这个参数必须是传递参考的.
当SWCommandAttribute.CommandType值为SWCommandType.InsertUpdate时,ParameterType属性值可能是SWParameterType.Key 和 SWParameterType.Identity
InsertUpdate( 插入-更新 ) 命令
一个 INSERT 或者 UPDATE SQL语句,非常琐碎,但是却很常用.我在SqlWrapper库中添加下面的命令和参数,可以简单第创建插入和更新数据到表的方法.
SWCommandType.InsertUpdate标识创建一个 特定的 插入-更新 表达式.
SWCommandAttribute.CommandText 必须是一个表的名称.
SWParameterType.Identity标识 参数是一个标识表列,用来标识一个行.这个值必须被传递参考.
SWParameterType.Key 标识 这个参数是一个主键的一部分(不是标识表列),用来标识一个行.
下面是两个 插入-更新 的例子.
1.方法定义:
[SWCommand(SWCommandType.InsertUpdate, "Shippers")]
public abstract void ShippersInsertUpdate
(
[SWParameter(SWParameterType.Identity)]ref int ShipperID,
[SWParameter(40)]string CompanyName,
[SWParameter(24)]string Phone
);
SQL语句:
if(@ShipperID is NULL)
begin
insert into [Shippers]([CompanyName], [Phone])
values(@CompanyName, @Phone)
select @ShipperID = SCOPE_IDENTITY()
end
else
begin
update [Shippers] set
[CompanyName]=@CompanyName,
[Phone]=@Phone
where [ShipperID]=@ShipperID
end
2.方法定义:
[SWCommand(SWCommandType.InsertUpdate, "Order Details")]
public abstract void OrderDetailsInsertUpdate
(
[SWParameter(SWParameterType.Key)]int OrderID,
[SWParameter(SWParameterType.Key)]int ProductID,
Decimal UnitPrice,
Int16 Quantity,
float Discount
);

SQL语句:

update [Order Details] set
[OrderID]=@OrderID,
[ProductID]=@ProductID,
[UnitPrice]=@UnitPrice,
[Quantity]=@Quantity,
[Discount]=@Discount
where [OrderID]=@OrderID and [ProductID]=@ProductID

if (@@rowcount = 0)
insert into [Order Details]([OrderID], [ProductID], [UnitPrice],
[Quantity], [Discount])
values(@OrderID, @ProductID, @UnitPrice, @Quantity, @Discount)


同你看到的一样,第一个例子中@ShipperID和NULL比较,默认的,这个值可能合适的是参数等于或者小于0.如果你要你能设置其他的值,你可以设置SWParameter.TreatAsNull属性,那么你设置的值将被转化为null.
在你的应用程序中创建数据访问层
SqlWrapper苦包含了基本的类:DataAccessLayerBase,它能够被利用很少的代码定制你自己的自定义数据访问层(DAL).所有要做的工作就是继承DataAccessLayerBase类,然后定义你要包装的类的属性如下:
public YourWrapperClass YourPropertyName
{
get
{
return (YourWrapperClass)GetWrapped();
}
}
这就是全部了.你可以添加任何其他你需要的成员.这个DAL的例子能创建上边的类Orders2,UserClass1.
public class MyDAL : DataAccessLayerBase
{
public UserClass1 UserClass1{get{return (UserClass1)GetWrapped();}}
public Orders2 Orders2{get{return (Orders2)GetWrapped();}}
}
这是一个DAL类的图:
这有一个如何使用你的数据访问层的例子:
MyDAL dal = new MyDAL();
dal.Init(cnn, true, true);
int c = dal.Orders2.CountByEmployee(6);
DataTable dt = dal.UserClass1.Method1();
在你使用一个DAL内的一个对象类,你要调用一个重载方法Init(),它继承于DataAccessLayerBase类.
public void Init(SqlConnection connection, bool autoCloseConnection,
bool ownsConnection);
public void Init(string connectionString, bool autoCloseConnection);
这些方法非常重要.因为在你连接设置属性外,他们调用一个私有方法,GenerateAllWrapper(),它列举了你DAL层中类的所有方法.创建包装对象和保存它们到一个私有的哈希表,m_swTypes:
private void GenerateAllWrapped()
{
MethodInfo[] mis = this.GetType().GetMethods();
for(int i = 0; i < mis.Length; ++i)
{
Type type = mis[i].ReturnType;
if(type.GetInterface(typeof(ISqlWrapperBase).FullName) ==
typeof(ISqlWrapperBase))
{
if(mis[i].Name.StartsWith("get_"))
{
if(!m_swTypes.ContainsKey(mis[i].Name))
{
ISqlWrapperBase sw = WrapFactory.Create(type);
m_swTypes[mis[i].Name] = sw;
}
}
}
}
}
你曾经定义的属性,调用包含方法GetWrapped(),将查找一个调用方法的名字,从m_swTypes返回一个正确的对象
protected ISqlWrapperBase GetWrapped()
{
MethodInfo mi = (MethodInfo)(new StackTrace().GetFrame(1).GetMethod());
ISqlWrapperBase res = (ISqlWrapperBase)m_swTypes[mi.Name];
if(res == null)
{
throw new SqlWrapperException("The object is not initialized.");
}
return res;
}
DataAccessLayerBase 使用下面三个方法,来简单第支持事务.
BeginTransaction() 和BeginTransaction(IsolationLevel iso) 打开一个新的事务.
RollbackTransaction() 回滚一个打开的事务.
CommitTransaction() 提交一个打开的事务.
包装类的Connection, Transaction 或者 AutoCloseTransaction属性将自动更新,当它们改变的时候.
另外,DataAccessLayerBase类还有几个方法(ExecuteDataSet(), ExecuteDataTable(), ExecuteScalar()和ExecuteNonQuery()),帮助你在特殊查询时使用sql语句.
在CodeProject上看了数据库的文章,感觉很好.性能也可以(感觉和访问数据库比,性能可以不计).就翻译了,水平有限,请指正. (翻译的不好的例子)
关于性能:
1.利用Emit减少性能损失http://yok.cnblogs.com/archive/2005/11/03/267952.html
2.反射性能分析: http://www.chinaitclub.org/forums/350/ShowPost.aspx
注: 在.NET2.0中,插入和更新不能使用,发生错误.
相关推荐
SQL数据生成器是一种工具,主要用于在数据库环境中快速创建和填充大量的测试或示例数据。它对于软件开发、性能测试、数据库设计验证等场景非常有用。通过使用这种工具,用户可以自定义数据规则,生成符合特定业务...
SQLServer的数据挖掘扩展了其OLAP功能,提供了预定义的算法,如关联规则、聚类、决策树和神经网络,用于发现数据中的模式和趋势。在实验中,你可能需要使用SQLServer的数据挖掘工具,如Data Mining Wizard,来创建和...
在Windows操作系统中,可以通过ODBC数据源管理器来配置新的数据源,选择适用于SQL Server的ODBC驱动,例如“SQL Server Native Client 10.0”(对应SQL Server 2008及更高版本),或者“SQL Server”(支持SQL ...
SQL Server是Microsoft公司推出的企业级数据库管理系统,支持标准的SQL语法,具备处理大规模数据、高并发访问以及复杂查询的能力。在进行负荷测试时,通常会生成大量的模拟数据以验证系统的稳定性和性能,这时批量...
SQL2000企业管理器是微软SQL Server 2000数据库系统的重要组成部分,它提供了一个图形化的用户界面,使得数据库管理员和开发人员能够轻松地管理和维护SQL Server实例。这个"SQL2000企业管理器绿色版"是精简版或者...
"SQL Server表数据导出成Insert语句的工具"是一个专门为此目的设计的应用程序,它能帮助数据库管理员和开发人员高效地生成插入语句,以便在其他数据库中重建同样的数据结构和内容。 1. **数据导出的需求**:在不同...
4. **数据控制语言(Data Control Language, DCL)**:用于控制数据的安全性和完整性,包括授权(GRANT)、撤销权限(REVOKE)、提交事务(COMMIT)、回滚事务(ROLLBACK)等语句。 #### 五、经典SQL练习题解析 ##...
为了实现数据的集中管理和分析,有时我们需要将这些控制器的数据与SQL Server数据库进行集成。本篇文章将深入探讨如何将Siemens S7 1200 PLC连接到SQL Server数据库,以便于数据的存储、查询和处理。 首先,理解...
Data row to insert sql是一个小的工具软件,可以将数据库表中指定数据转换成相应的insert sql语句。目前支持的数据库类型为oracle,db2,ms sql server。 目前还有一些缺陷,还有待完善,具体如下: 1、对ms sql ...
4. **数据查询和分析**:一旦数据导入成功,用户可以使用SQL查询语言对这些全球国家和城市数据进行各种分析,比如查找特定国家的所有城市,或者计算某个地区的人口总量。 【标签】 "数据库 数据 国家 全世界" 暗示...
这个过程涉及到SQL语法的转换,因为SQL Server和Oracle虽然都遵循SQL标准,但各自的语法特性和函数库有所不同。例如,SQL Server的T-SQL和Oracle的PL/SQL在存储过程编写上就有显著差异。 标签"sql 工具"表明我们...
首先,三层架构是一种常见的软件设计模式,它将应用程序分为表现层(UI)、业务逻辑层(BLL)和数据访问层(DAL)。DbHelperSQL位于数据访问层,负责与数据库进行交互,为业务逻辑层提供数据服务。表现层通过调用...
SQL 数据类型 SQL 服务器 SQL 函数 SQL functions SQL avg() SQL count() SQL first() SQL last() SQL max() SQL min() SQL sum() SQL Group By SQL Having SQL ucase() SQL lcase() SQL mid() SQL ...
在VB(Visual Basic)编程中,访问和操作数据库是常见的任务,尤其是对于初学者来说,了解如何使用SQL语句从Access数据库中读取并显示数据是基础技能之一。本实例将详细讲解如何实现这一功能。 首先,我们需要引入...
在SQLSERVER数据库的使用过程中,有时会出现一个棘手的问题,即驱动程序无法通过安全套接字层(SSL)加密与SQL Server建立安全连接。这个问题通常表明数据库连接在尝试使用SSL进行加密时遇到了障碍,可能影响数据的...
中国所有唐诗数据(SQL文件)。 在数据库管理工具执行SQL脚本即可,没有建库只有建表和插入语句,需要自己创建数据库。 包含中国所有唐诗。
3. **数据访问层(DAL)**:直接与数据库通信,执行SQL查询和存储过程。在这个案例中,数据库为SQL Server 2005,DAL可能包含ADO.NET对象,如SqlConnection、SqlCommand等,用于连接、查询和更新数据库。 **ASP.NET...
Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(一) http://download.csdn.net/source/3268267 Oracle 11g SQL和PL SQL从入门到精通 pdf格式电子书 下载(二) ...
这个“SQL Server 2000 msde2000企业管理器绿色免安装版”是一个便携式、无需正式安装的版本,便于用户快速启动和使用。 企业管理器是SQL Server的重要组成部分,它是一个图形用户界面工具,用于管理和维护SQL ...
系统设计时,可以采用三层架构:表现层(用户界面)、业务逻辑层(C/C++代码实现)和数据访问层(SQL数据库)。表现层负责接收用户输入,展示结果;业务逻辑层处理输入数据,执行计算,调用数据库操作;数据访问层则...