小弟不才,写了个DbHelper,各位大牛来指点一下
--------------------编程问答-------------------- --------------------编程问答-------------------- 怎么给分 --------------------编程问答-------------------- --------------------编程问答-------------------- 不错,抽象工程呀 --------------------编程问答-------------------- --------------------编程问答----------------------------------------编程问答-------------------- 我不需要代码,我想有我自己的代码,哪怕是抄,我也要一个字符一个字符自己敲出来,理解它,这样心里才有底,自己的东西,自己用了顺手。
Imports System.Data.Common
Imports System.Globalization
Public Enum DbProviderFactoryType
Odbc
OleDb
OracleClient
SqlClient
SqlServerCe_3_5
End Enum
Public Class DataBase
Private connectionString As String
Private providerFactory As DbProviderFactory
''' <summary>
''' 构造函数
''' </summary>
''' <param name="connectionString">连接字符串</param>
''' <param name="providerInvariantName">
''' System.Data.Odbc
''' System.Data.OleDb
''' System.Data.OracleClient
''' System.Data.SqlClient
''' System.Data.SqlServerCe.3.5</param>
''' <remarks></remarks>
Public Sub New(ByVal connectionString As String, ByVal providerInvariantName As String)
providerFactory = Common.DbProviderFactories.GetFactory(providerInvariantName)
Me.connectionString = connectionString
End Sub
Public Sub New(ByVal connectionStringBuilder As System.Data.Common.DbConnectionStringBuilder, ByVal providerInvariantName As String)
providerFactory = Common.DbProviderFactories.GetFactory(providerInvariantName)
connectionString = connectionStringBuilder.ToString
End Sub
Public Sub New(ByVal connectionString As String, ByVal providerFactory As DbProviderFactoryType)
Me.providerFactory = Common.DbProviderFactories.GetFactory(("System.Data." & providerFactory.ToString).Replace("_"c, "."c))
Me.connectionString = connectionString
End Sub
Public Sub New(ByVal connectionStringBuilder As System.Data.Common.DbConnectionStringBuilder, ByVal providerFactory As DbProviderFactoryType)
Me.providerFactory = Common.DbProviderFactories.GetFactory(("System.Data." & providerFactory.ToString).Replace("_"c, "."c))
Me.connectionString = connectionStringBuilder.ToString
End Sub
Public Sub New(ByVal connectionString As String)
Me.providerFactory = Common.DbProviderFactories.GetFactory(ConfigurationManager.ConnectionStrings(connectionString).ProviderName)
Me.connectionString = ConfigurationManager.ConnectionStrings(connectionString).ConnectionString
End Sub
Public Function ExecuteGetNon(ByVal sql As String) As Integer
ExecuteGetNon = ExecuteGetNon(sql, Nothing)
End Function
Public Function ExecuteGetNon(ByVal sql As String, ByVal dbParameter() As DbParameter) As Integer
Using conn As DbConnection = providerFactory.CreateConnection
conn.ConnectionString = connectionString
Using cmd As DbCommand = providerFactory.CreateCommand
conn.Open()
cmd.Connection = conn
cmd.CommandText = sql
If dbParameter IsNot Nothing Then
cmd.Parameters.AddRange(dbParameter)
End If
ExecuteGetNon = cmd.ExecuteNonQuery()
End Using
End Using
End Function
Public Function ExecuteGetGrid(ByVal sql As String) As Object
ExecuteGetGrid = ExecuteGetGrid(sql, Nothing)
End Function
Public Function ExecuteGetGrid(ByVal sql As String, ByVal dbParameter() As DbParameter) As Object
Using conn As DbConnection = providerFactory.CreateConnection
conn.ConnectionString = connectionString
Using cmd As DbCommand = providerFactory.CreateCommand
conn.Open()
cmd.Connection = conn
cmd.CommandText = sql
If dbParameter IsNot Nothing Then
cmd.Parameters.AddRange(dbParameter)
End If
ExecuteGetGrid = cmd.ExecuteScalar()
End Using
End Using
End Function
Public Function ExecuteGetTable(ByVal sql As String) As DataTable
ExecuteGetTable = ExecuteGetTable(sql, Nothing)
End Function
Public Function ExecuteGetTable(ByVal sql As String, ByVal dbParameter() As DbParameter) As DataTable
Dim tempTable As New DataTable
tempTable.Locale = CultureInfo.InvariantCulture
Using conn As DbConnection = providerFactory.CreateConnection
conn.ConnectionString = connectionString
Using cmd As DbCommand = providerFactory.CreateCommand
conn.Open()
cmd.Connection = conn
cmd.CommandText = sql
If dbParameter IsNot Nothing Then
cmd.Parameters.AddRange(dbParameter)
End If
Using rdr As DbDataReader = cmd.ExecuteReader
tempTable.Load(rdr)
tempTable.TableName = "myTable"
ExecuteGetTable = tempTable
End Using
End Using
End Using
End Function
Public Function ExecuteGetDataSet(ByVal sql As String) As DataSet
ExecuteGetDataSet = ExecuteGetDataSet(sql, Nothing)
End Function
Public Function ExecuteGetDataSet(ByVal sql As String, ByVal dbParameter() As DbParameter) As DataSet
Dim tempDataSet As New DataSet
tempDataSet.Locale = CultureInfo.InvariantCulture
Using conn As DbConnection = providerFactory.CreateConnection
conn.ConnectionString = connectionString
Using da As DbDataAdapter = providerFactory.CreateDataAdapter
conn.Open()
Using cmd As DbCommand = providerFactory.CreateCommand
cmd.Connection = conn
cmd.CommandText = sql
If dbParameter IsNot Nothing Then
cmd.Parameters.AddRange(dbParameter)
End If
da.SelectCommand = cmd
End Using
da.Fill(tempDataSet)
ExecuteGetDataSet = tempDataSet
End Using
End Using
End Function
End Class
--------------------编程问答-------------------- 不错不错不错不错 --------------------编程问答-------------------- 可以看看微软写的sqlhelper类是怎么写的 借鉴一下 --------------------编程问答-------------------- 我就是借鉴了很多,petshop,还有很多网友的,然后弄了这个,我的目的是让大牛们帮我找出毛病
--------------------编程问答-------------------- #region 执行命令返回受影响行数
public int ExecuteCmd(DbCommand cmd)
{
int ExecuteNums = 0;
cmd.Connection.Open();
ExecuteNums = cmd.ExecuteNonQuery();
cmd.Connection.Close();
cmd.Parameters.Clear();
return ExecuteNums;
}
public int ExecuteCmd(DbCommand cmd, Trans t)
{
int ExecuteNums = 0;
cmd.Connection = t.DbTrans.Connection;
cmd.Transaction = t.DbTrans;
ExecuteNums = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return ExecuteNums;
}
为什么通过重载实现事务呢,为什么不把trans 提取出来在写个方法呢
比如
将来调用
class1{
add(){
ExecuteCmd("insert sql1");
}
}
class2{
add(){
ExecuteCmd("isnert sql2");
}
}
分别调用
class1.add();
class2.add();
事务调用时你怎么写呀,再修改一下add()方法吗?
--------------------编程问答--------------------
微软写的sqlhelper就是一坨易做图
--------------------编程问答-------------------- 为什么不把DbConnection 定义为属性呢?将来得用是
DbConnection dbc= createConection();
DbCommand 就不要写成参数啦,string 改成commmandtext作为参数,否则,dbCommand我在方法外就可以操作啦,那还传到方法干什么 --------------------编程问答-------------------- ibatis的框架可以看看,代码比一般写的dbhelper有价值,又比大框架的代码少的多 --------------------编程问答-------------------- 事物我是在调用的时候new一个,我是考虑到线程安全,而且底层我全部去掉try catch,留在外层捕获,保证线程安全的同时能够捕获异常
--------------------编程问答-------------------- 属性那个我暂时无需外部调用,所有db操作必须通过dbhelper的方法操作,至于cmd做参数是考虑到带参数sqltext,使用的时候createcmd就行了
--------------------编程问答-------------------- 谢谢,我去看下
--------------------编程问答-------------------- 还行
太短了还不让我发 --------------------编程问答-------------------- 再补充,因为我去掉了底层的try catch,所以我必须要在外部
using ( dbcommand cmd = dbhelper.createcmd("")){
//
}
来保证cmd的connection等非托管资源的释放
--------------------编程问答-------------------- 很没意思 网上一搜一堆的东西啊 --------------------编程问答-------------------- 第一,我是外行,.net是我业余爱好,前来请教
第二,对于技术类的东西,我希望弄明白,弄透,不想离开了VS,离开了类库,我就不会编码了
第三,我有易做图症
第四,可能对你来说,你看不上,没意思,但是对我这个菜鸟来说,我觉得很有意思
--------------------编程问答-------------------- 没用抽象工厂写过DBHelper,不过感觉你这个写的很累赘,有些是可以写成一个方法的,你在里面判断传进来的条件不就行了吗? --------------------编程问答-------------------- 之所以这样,我是想把底层的东西做个彻底的封装,其次要适应多种应用环境,还有线程安全,代码优化等等。
还有,之所以请教大家主要是关于设计模式,框架方面方面的问题,其他纯业务逻辑,具体技术性的东西,我自己去Google就行了
--------------------编程问答-------------------- 这也不才,LEVEL比我高多了 --------------------编程问答-------------------- --------------------编程问答-------------------- 还好吧 --------------------编程问答-------------------- 其实路过的想问 ncf支持抽象工厂了吗 T T --------------------编程问答-------------------- 问题多多,比如分布式事务支持;外部已启动事务的情况等 --------------------编程问答-------------------- 要看自已写的DBHelper到底如何,可下载微软企业库来比比。
注:微软企业库有一个专门数据访问模块。 --------------------编程问答-------------------- 习惯用数据库映射框架的飘过.... --------------------编程问答-------------------- 看了你的代码,我觉得这里代码有些建议
public int ExecuteCmd(DbCommand cmd)
{
int ExecuteNums = 0;
cmd.Connection.Open();
ExecuteNums = cmd.ExecuteNonQuery();
cmd.Connection.Close();
cmd.Parameters.Clear();
return ExecuteNums;
}
cmd.Connection.Open(); --这里注意
最好是在Try catch fianlly 中实现代码,保证每一次执行查询数据库链接均被关闭。
这样做好处在于,你在分布式系统中数据访问层一般是在服务器执行,客户发送SQL之类到服务器端执行,
万一某功能SQL有误,就会造成你服务器数据连接一直打开状态,未实现关闭,会影响其他客户端提交的服务端执行SQL。 反正用到数据连接的地方,建议还是在Try 中进行控制。
第二个意见:未加入数据库执行的事务控制,可能单机、局域网中问题很少,但是一旦网络环境问题,事务处理提交数据是很有效的手段,关于事务可以看看网络上,在你代码里面加入也简单。
第三个意见:(可自行考虑是否需要)数据库连接的安全性,一般在采用密文在app.config 中,在代码中使用揭秘,最好是使用对称性加密算法,网上也多。
--------------------编程问答-------------------- 各位都很有才,跟在大家后面学习吧! --------------------编程问答-------------------- 我记得DbHelper好像网上有个现成的代码,你可以搜搜看作参考 --------------------编程问答-------------------- 我也来一个,凑凑热闹。
理论上只要app.config或web.config的connectionString配置节的信息正确,可以做到兼容所有支持ADO.NET的数据库。
该类实现了 IDisposable 接口,调用 Dispose() 方法释放连接资源。
[code=C#]
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Linq;
using Inbar.Inte易做图ce;
namespace Inbar.Repository
{
/// <summary>
/// 表示连接到的关系型数据库。它由访问关系型数据库的 ADO.NET 数据提供程序实现。
/// </summary>
public class DbNativeClient : IDisposable
{
bool disposed = false;
DbProviderFactory _factory;
DbConnectionStringBuilder _builder;
DbConnection _connection;
/// <summary>
/// 获取关系型数据库所使用的 <see cref="System.Data.Common.DbConnection"/> 连接对象。
/// </summary>
public DbConnection Connection
{
get
{
if (_connection == null)
{
_connection = _factory.CreateConnection();
_connection.ConnectionString = _builder.ToString();
}
switch (_connection.State)
{
case ConnectionState.Broken:
_connection.Close();
_connection.Open();
break;
case ConnectionState.Closed:
_connection.Open();
break;
}
return _connection;
}
}
/// <summary>
/// 使用指定的连接字符串配置节,初始化 <see cref="Inbar.Repository.DbNativeClient"/>
/// 数据库的连接对象。
/// </summary>
/// <param name="sectionName">配置节的名称</param>
/// <exception cref="System. Configuration.ConfigurationErrorsException">当无法找到指定的连接字符串配置节时将引发该异常。</exception>
public DbNativeClient(string sectionName)
{
ConnectionStringSettings section = ConfigurationManager
.ConnectionStrings[sectionName];
if (section == null)
{
throw new ConfigurationErrorsException();
}
_builder = new DbConnectionStringBuilder();
_builder.ConnectionString = section.ConnectionString;
_factory = DbProviderFactories.GetFactory(section.ProviderName);
}
/// <summary>
/// 使用一个现有的数据库连接,初始化 <see cref="Inbar.Repository.DbNativeClient"/>
/// 类的新实例。
/// </summary>
/// <param name="connection">现有的数据库连接实例</param>
/// <exception cref="System.ArgumentNullException">connection 为 null。</exception>
public DbNativeClient(DbConnection connection)
{
if (connection==null)
{
throw new ArgumentNullException("connection");
}
_factory = DbProviderFactories.GetFactory(connection);
_builder.ConnectionString = connection.ConnectionString;
_connection = connection;
}
/// <summary>
/// 使用指定的连接字及抽象的数据源提供程序, 初始化 <see cref="Inbar.Repository.DbNativeClient"/> 数据库的连接对象。
/// </summary>
/// <param name="connectionString">连接字符串</param>
/// <param name="provider">抽象的数据源提供程序</param>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="provider"/> 为 null 时,将引发该异常。
/// </exception>
public DbNativeClient(string connectionString, DbProviderFactory provider)
{
if (provider == null)
{
throw new ArgumentNullException("provider", "数据源提供程序为 null。");
}
_builder = new DbConnectionStringBuilder();
_builder.ConnectionString = connectionString;
_factory = provider;
}
/// <summary>
/// 返回与提供程序所连接的数据库类型相关的
/// <see cref="System.Data.Common.DbParameter"/> 查询参数。
/// </summary>
/// <param name="name">参数名称</param>
/// <param name="value">参数值</param>
/// <returns>一个与提供程序相关的查询参数。</returns>
public DbParameter CreateParameter(string name, object value)
{
return CreateParameter(name, DbType.String, ParameterDirection.Input, value);
}
/// <summary>
/// 返回与提供程序所连接的数据库类型相关的
/// <see cref="System.Data.Common.DbParameter"/> 查询参数。
/// </summary>
/// <param name="name">参数名称</param>
/// <param name="dbType">参数类型</param>
/// <param name="value">参数值</param>
/// <returns>一个与提供程序相关的查询参数。</returns>
public DbParameter CreateParameter(string name, DbType dbType, object value)
{
return CreateParameter(name, dbType, ParameterDirection.Input, value);
}
/// <summary>
/// 返回与提供程序所连接的数据库类型相关的
/// <see cref="System.Data.Common.DbParameter"/> 查询参数。
/// </summary>
/// <param name="name">参数名称</param>
/// <param name="dbType">参数类型</param>
/// <param name="direction">参数方向</param>
/// <param name="value">参数值</param>
/// <returns>一个与提供程序相关的查询参数。</returns>
public DbParameter CreateParameter(string name, DbType dbType,
ParameterDirection direction, object value)
{
DbParameter para = _factory.CreateParameter();
para.ParameterName = name;
para.DbType = dbType;
para.Direction = direction;
para.Value = value;
return para;
}
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回查询结果集的只进读取流。
/// </summary>
/// <param name="sql">SQL 查询命令</param>
/// <param name="parameters">提供的查询参数</param>
/// <returns>返回查询结果的只进读取流。</returns>
public DbDataReader ExecuteReader(string sql, params DbParameter[] parameters)
{
return ExecuteReader(sql, CommandType.Text, CommandBehavior
.Default, parameters);
}
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回查询结果集的只进读取流。
/// </summary>
/// <param name="sql">SQL 查询命令</param>
/// <param name="behavior">查询结果和查询对数据库的影响的说明</param>
/// <param name="parameters">提供的查询参数</param>
/// <returns>返回查询结果的只进读取流。</returns>
public DbDataReader ExecuteReader(string sql, CommandBehavior behavior,
params DbParameter[] parameters)
{
return ExecuteReader(sql, CommandType.Text, behavior, parameters);
}
/// <summary>
/// 创建一个原始 SQL 查询,该查询将返回查询结果集的只进读取流。
/// </summary>
/// <param name="sql">SQL 查询命令</param>
/// <param name="type">命令的类型</param>
/// <param name="behavior">查询结果和查询对数据库的影响的说明</param>
/// <param name="parameters">提供的查询参数</param>
/// <returns>返回查询结果的只进读取流。</returns>
public DbDataReader ExecuteReader(string sql, CommandType type,
CommandBehavior behavior, params DbParameter[] parameters)
{
DbCommand cmd = Connection.CreateCommand();
cmd.CommandType = type;
cmd.CommandText = sql;
if (parameters.Length > 0)
{
cmd.Parameters.AddRange(parameters);
}
return cmd.ExecuteReader(behavior);
}
/// <summary>
/// 使用断开式数据适配器填充并返回一个 <see cref="System.Data.DataSet"/> 对象的实例。
/// </summary>
/// <param name="sql">SQL 查询命令</param>
/// <param name="parameters">提供的查询参数</param>
/// <returns>返回由数据适配填充的 <see cref="System.Data.DataSet"/>。</returns>
public DataSet ExecuteDataSet(string sql, params DbParameter[] parameters)
{
return ExecuteDataSet(sql, CommandType.Text, parameters);
}
/// <summary>
/// 使用断开式数据适配器填充并返回一个 <see cref="System.Data.DataSet"/> 对象的实例。
/// </summary>
/// <param name="sql">SQL 查询命令</param>
/// <param name="type">命令的类型</param>
/// <param name="parameters">提供的查询参数</param>
/// <returns>返回由数据适配填充的 <see cref="System.Data.DataSet"/>。</returns>
public DataSet ExecuteDataSet(string sql, CommandType type,
params DbParameter[] parameters)
{
DataSet ds = new DataSet();
DbCommand cmd = Connection.CreateCommand();
cmd.CommandText = sql;
cmd.CommandType = type;
if (parameters.Length > 0)
{
cmd.Parameters.AddRange(parameters);
}
DbDataAdapter adapter = _factory.CreateDataAdapter();
adapter.SelectCommand = cmd;
adapter.Fill(ds);
return ds;
}
--------------------编程问答-------------------- 上接
--------------------编程问答-------------------- 感觉复杂了,封装那多干哈, 喜欢简单点的 --------------------编程问答-------------------- 纠结这种通用类安全优化很没意思 ,自己业务的核心类好好优化才是正道 --------------------编程问答--------------------
/// <summary>
/// 针对 .NET Framework 数据提供程序的 Connection 对象执行 SQL 语句,
/// 并返回受影响的行数。
/// </summary>
/// <param name="sql">SQL 查询命令</param>
/// <param name="parameters">提供的查询参数</param>
/// <returns>返回受影响的行数。</returns>
public int ExecuteNonQuery(string sql, params DbParameter[] parameters)
{
return ExecuteNonQuery(sql, CommandType.Text, parameters);
}
/// <summary>
/// 针对 .NET Framework 数据提供程序的 Connection 对象执行 SQL 语句,
/// 并返回受影响的行数。
/// </summary>
/// <param name="sql">SQL 查询命令</param>
/// <param name="type">命令的类型</param>
/// <param name="parameters">提供的查询参数</param>
/// <returns>返回受影响的行数。</returns>
public int ExecuteNonQuery(string sql, CommandType type,
params DbParameter[] parameters)
{
DbCommand cmd = Connection.CreateCommand();
cmd.CommandText = sql;
cmd.CommandType = type;
if (parameters.Length > 0)
{
cmd.Parameters.AddRange(parameters);
}
return cmd.ExecuteNonQuery();
}
/// <summary>
/// 执行指定的 Sql 命令,并返回首行首列的单个值。
/// </summary>
/// <typeparam name="TResult">返回值的类型</typeparam>
/// <param name="sql">SQL 查询命令</param>
/// <param name="parameters">提供的查询参数</param>
/// <returns>返回指定类型的首行首列的值。</returns>
/// <remarks>当数据库返回 null 或无法强制转换为 <typeparamref name="TResult"/>
/// 类型时,将返回该类型的默认值。
/// </remarks>
public TResult ExecuteScalar<TResult>(string sql, params DbParameter[] parameters)
{
return ExecuteScalar<TResult>(sql, CommandType.Text, parameters);
}
/// <summary>
/// 执行指定的 Sql 命令,并返回首行首列的单个值。
/// </summary>
/// <typeparam name="TResult">返回值的类型</typeparam>
/// <param name="sql">SQL 查询命令</param>
/// <param name="type">命令的类型</param>
/// <param name="parameters">提供的查询参数</param>
/// <returns>返回指定类型的首行首列的值。</returns>
/// <remarks>当数据库返回 null 或无法强制转换为 <typeparamref name="TResult"/>
/// 类型时,将返回该类型的默认值。
/// </remarks>
public TResult ExecuteScalar<TResult>(string sql, CommandType type,
params DbParameter[] parameters)
{
TResult result = default(TResult);
DbCommand cmd = Connection.CreateCommand();
cmd.CommandText = sql;
cmd.CommandType = type;
if (parameters.Length > 0)
{
cmd.Parameters.AddRange(parameters);
}
object obj = cmd.ExecuteScalar();
try
{
result = (TResult)Convert.ChangeType(obj, typeof(TResult));
}
catch { }
return result;
}
/// <summary>
/// 关闭已打开的数据库连接并释放连接对象所使用的资源。
/// </summary>
/// <param name="disposing">如果为 true,则同时释放托管资源和非托管资源;
/// 如果为 false,则仅释放非托管资源。</param>
protected void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
//TODO: 在此释放托管资源
}
//释放非托管资源
if (_connection != null)
{
if (_connection.State != ConnectionState.Closed)
{
_connection.Close();
_connection.Dispose();
}
_connection = null;
}
//将标记设置为:资源已释放
disposed = true;
}
}
/// <summary>
/// 关闭数据库连接并销毁连接对象。
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// 返回当前实例所使用的数据库连接字符串。
/// </summary>
/// <returns>数据库连接字符串。</returns>
public override string ToString()
{
return _builder.ToString();
}
}
}
不足之处应该指出,我想他想在需要的是一点鼓励 --------------------编程问答-------------------- 我以前也写过这些类似的小玩意儿,后来发现其实也就是熟悉一下语法和一些数据库有关的东西而已。不要太纠结于这些“通用”结构。 --------------------编程问答-------------------- 这种级别的封装没有意义,不如看看net的实体。 --------------------编程问答-------------------- 1、对于事务的处理不够好楼上已经说了
2、线程安全方面很差劲 --------------------编程问答-------------------- 顺便说一下吧,我认为dbhelper这种方式显得有点过时了。
手动去写sql语句的话,很明显容易出错。
可以使用下像Entity framework这类orm会比较好有用 --------------------编程问答-------------------- 我擦,楼上的你以为你是艺术家?一看就是个易做图人,Entity framework这类的东西你又用过多少?各有各的优点,小易做图孩不要出来乱叫。 --------------------编程问答-------------------- 我擦,楼上的你以为你是艺术家?一看就是个易做图人,Entity framework这类的东西你又用过多少?各有各的优点,小易做图孩不要出来乱叫。 --------------------编程问答-------------------- 楼上说的好对啊 --------------------编程问答-------------------- --------------------编程问答-------------------- 顶43 44楼说的 --------------------编程问答-------------------- 楼上是害怕使用Entity framework吧,驾驭不了。 --------------------编程问答-------------------- 43\44楼是畜生,大家别介意 --------------------编程问答-------------------- 虽然做轮子不是啥有意义的,不过好玩就行,咱玩的就是这。。啥都用别人的,自己还玩鸟啊。。
编程就是用来玩玩的。。framework 学太多那可浪费生命。。 --------------------编程问答-------------------- 还是看MS的算了。。。 --------------------编程问答-------------------- 楼主采用了抽象工厂的模式实现,但是没有考虑Sql注入的问题吧? --------------------编程问答-------------------- --------------------编程问答-------------------- SqlServerCe_3_5
这都有 太有才了,
楼主写的 不是很好,为什么那?如下:
第一:
你没有更好的封装 功能。
只有一个工厂,而且你的工厂意义不大,最好的方式 你应该是 loadFile(DLL 文件) //比如MySql.Dll
对于事物和参数化的处理也没有。
继承就那么一回事情,没有什么好说的,
而且这里 有一个 抽象类是不够,你要用 接口来实现特殊化。
一个完整的 最少要 3000 行左右的代码 ,还要带着 反射来进行 对象的 转换,比如 entity to List ,DataTable To Entity 等等。
如果只加一个壳那我觉得你直接一个 loadFile就解决了 连引用都不添加,那才叫全工厂GAC 操作了。 --------------------编程问答-------------------- 就一个 ExecuteDataReader 什么的 就得重载 9个估计。少的话也的 4个。 --------------------编程问答-------------------- 所有的都要 进行重载 目的是给外面提供一个 完全的 参数化数据方式。 --------------------编程问答-------------------- 可以参考下动软的help。 --------------------编程问答-------------------- 使用using可以不用操心连接释放的问题
补充:.NET技术 , C#