第一次写东西 各位大大海涵

一个系统执行一个数据操作的步骤:

1.连接数据库。

2.构建Sql 语句。

3.执行语句。

4.返回 执行结果。

实例代码下载实例代码下载

注:

     一个系统可能有 N 个操作 ,然后另一个系统也要执行数据访问操作,那么我们可以不可以把连接数据、库执行语句、返回结果

写成一个公共的东西呢? 答案是一定的。例如:NHibernate 我们只要引用它的类库、配置数据库连接语句和Mapping 文件 就可以

进行操作了。那我今天说的是 不用写配置文件 的一个 公用数据库操作类库。暂时只实现查询

首先我们编写一个接口:


 CustomDataOperate.Data.DataProviders
{
    public interface IDataProvider
    {
        DbConnection OpenConnection();

        
void Open();

        
void Close();

        IDataReader ExecuteReader(
string sql);

        
int ExecuteNonQuery(string sql);

        ICollection
<TEntity> ExcuteReader<TEntity>(string sql) where TEntity : class;
    }
}


 DbConnection OpenConnection(); 打开一个数据库连接

  void Open(); 当连接为关闭状态时 再次打开连接

  void Close(); 关闭连接

  IDataReader ExecuteReader(
string sql); 执行Sql 语句返回执行结果

  int ExecuteNonQuery(
string sql); 执行 修改、删除、增加

  ICollection<TEntity> ExcuteReader<TEntity>(string sql) where TEntity : class;  执行查询返回对象集合 


然后为接口写一个抽象类:

 CustomDataOperate.Data.DataProviders
{
    public abstract class DataProviderBase : IDataProvider
    {

        
protected DbConnection _Connection;
        
protected DbCommand _Command;
        
protected IEntityTranslate _Translate;

        
#region IDataProvider Members

        
public abstract DbConnection OpenConnection();

        
public virtual void Close()
        {
            _Connection.Close();
        }

        
public virtual void Open()
        {
            _Connection.Open();
        }


        
protected virtual DbCommand Command
        {
            
get { return _Command; }
            
set { _Command = value; }
        }


        
protected IEntityTranslate Translate
        {
            
get
            {
                
if (_Translate == null)
                {
                    _Translate 
= new EntityTranslate();
                }
                
return _Translate;
            }
        }

        
public abstract IDataReader ExecuteReader(string sql);

        
public abstract int ExecuteNonQuery(string sql);

        
public abstract ICollection<TEntity> ExcuteReader<TEntity>(string sql) where TEntity : class;

        
#endregion
    }

在 DataProviderBase 中出现了 Translate 属性 他是什么呢 ? 他是一个 (IEntityTranslate) 转换器

 将IDataReader 转换为Entity


代码如下:

 CustomDataOperate.Data.Translates
{
    public interface IEntityTranslate
    {
        TEntity Translate
<TEntity>(IDataReader reader) where TEntity : class;
    }
}

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using MD = CustomDataOperate.Data.Attributes;
using System.Reflection;

namespace CustomDataOperate.Data.Translates
{
    
public class EntityTranslate:IEntityTranslate
    {
        
public TEntity Translate<TEntity>(IDataReader reader) where TEntity : class
        {
            Type entityType 
= typeof(TEntity);

            
object entity = Activator.CreateInstance(entityType);
            
foreach (PropertyInfo info in entityType.GetProperties())
            {
                
string columnName = string.Empty;

                
object[] attributes = info.GetCustomAttributes(true);
                
foreach (object attribute in attributes)
                {
                    
if (attribute is MD.DataColumn)
                    {
                        columnName 
= (attribute as MD.DataColumn).ColumnName;
                        
int filedIndex = 0;
                        
while (filedIndex < reader.FieldCount)
                        {
                            
if (reader.GetName(filedIndex) == columnName)
                            {
                                info.SetValue(entity, reader.GetValue(filedIndex), 
null);
                                
break;
                            }
                            filedIndex
++;
                        }
                        
break;
                    }
                }
            }
            
return entity as TEntity;
        }
    }
}



 

为什么转换器中会出现 DataColumn 是 System.Data 命名空间下的吗? 不是 这是一个自定义的 Attirbute

 CustomDataOperate.Data.Attributes
{
    public class DataColumn : System.Attribute
    {
        
public DataColumn()
        {
        }

        
public DataColumn(string columnName)
        {
            ColumnName 
= columnName;
        }

        
public string ColumnName
        {
            
get;
            
set;
        }
    }
}
注释:

      ColumnName :将数据库的Filed 和 Entity Property 对应。


到这里还要做什么呢? 对了还缺少实现,那么我们开始实现这个 Provider


 CustomDataOperate.Data.SqlDataProviders
{
    public class SqlDataProvider :DataProviderBase
    {

        
private void BuilderCommand(string sql)
        {
            Command.CommandText 
= sql;
            Command.Connection 
= OpenConnection();
        }

        
public override System.Data.Common.DbConnection OpenConnection()
        {
            
if (_Connection == null)
            {
                _Connection 
= BuilderSqlConnection();
            }

            
if (_Connection.State != System.Data.ConnectionState.Open)
            {
                Open();
            }
            
return _Connection;
        }

        
private System.Data.Common.DbConnection BuilderSqlConnection()
        {
            
try
            {
                
string connectionString = ConfigurationManager.ConnectionStrings["DataBaseConnectionString"].ConnectionString;
                
return new SqlConnection(connectionString);
            }
            
catch (Exception ex)
            {
                
throw new Exception("數據庫鏈接失敗! 失敗原因:" + ex);
            }
        }

        
protected override System.Data.Common.DbCommand Command
        {
            
get
            {
                
if (base.Command == null)
                {
                    
base.Command = new SqlCommand();
                }
                
return base.Command;
            }
            
set
            {
                
base.Command = value;
            }
        }

        
public override IDataReader ExecuteReader(string sql)
        {
            BuilderCommand(sql);
            
return Command.ExecuteReader();
        }

        
public override int ExecuteNonQuery(string sql)
        {
            BuilderCommand(sql);
            
return Command.ExecuteNonQuery();
        }


        
public override ICollection<TEntity> ExcuteReader<TEntity>(string sql)
        {
            ICollection
<TEntity> datas = new List<TEntity>();
            BuilderCommand(sql);
            
using (IDataReader reader = Command.ExecuteReader())
            {
                
while (reader.Read())
                {
                    datas.Add(Translate.Translate
<TEntity>(reader));
                }
            }
            
return datas;
        }
    }

好了准备工作做好了!那么我们开始测试吧:

既然测试那么不能少了数据库:


CREATE TABLE Customer(
[CustomerID] [int] NOT NULL,
[CustomerName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,

)

添加两条数据:
100001 測試修改客戶1212
100002 SecondCus

准备一个Entity:

 Customer
{
    public Customer()
    {}
    
    
public Customer(int customerID,string customerName)
    {
        CustomerID 
=customerID;
        CustomerName 
=customerName;    
    }
    
    [DataColumn(
"CustomerID")]
    
public int CustomerID
    {
        
get;
        
set;
    }
    [DataColumn(
"CustomerName")]
    
public string CustomerName
    {
        
get;
        
set;
    }
}

是不是发现 Entity中出现了 [DataColumn("CustomerID")] 呢! 对了 这里就是将数据库的列和Entity对应上。

伟大的时刻要即将到来:



        private IDataProvider _Provider;

        [TestInitialize]
        
public void Init()
        {
            _Provider 
= new SqlDataProvider();
        }


        [TestMethod()]
        
public void ExcuteReaderTest()
        {
            
string sql = "select * from customer";
            ICollection
<Customer> customers = _Provider.ExcuteReader<Customer>(sql);
            Assert.IsNotNull(customers);
            
foreach (Customer customer in customers)
            {
                Console.WriteLine(
"{0}   {1}", customer.CustomerID, customer.CustomerName);
            }
输出结果:
100001 測試修改客戶1212
100002 SecondCus

Yes 成功了!


相关文章:

  • 2022-12-23
  • 2021-12-04
  • 2021-12-04
  • 2021-09-29
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-05-18
猜你喜欢
  • 2021-12-04
  • 2021-11-28
  • 2022-12-23
  • 2021-07-09
  • 2021-05-25
  • 2021-08-01
  • 2022-12-23
相关资源
相似解决方案