摘要:最近有病呆在家里,不是次就是睡,不只日夜颠倒了,还胖了不少。不过空余的时间总不能浪费掉,所以开始了一个新的跨数据库访问组件。不过那个组件要写比较长时间了,所以一时不会做得完。不过今天用其中的技术做了个有用的例子,发到这里给大家参考一下。这个例子的大概意思是,程序员参考存储的定义,写出一个接口出来,并且不需要写具体的实现代码,就能调用该接口了!也就是说,程序员不需要写以下类似的代码了: SqlCommand cmd=new SqlCommand("UpdateTopic",conn);cmd.CommandType=CommandType.StoredProcedure;SqlParameter pTitle=new SqlParameter("@title",SqlDbType.NVarChar,80);pTitle.Value=title;cmd.Parameters.Add(pTitle);//. 程序的例子如下 /**//****************************************************************\ *  * 用 System.Reflection.Emit 来自动生成调用储存过程的实现! *  * By http://lostinet.com *  * Copyrights : Not-Reversed * \****************************************************************///使用的例子namespace Lostinet.Sample{    using System;    using System.Data;    using System.Data.SqlClient;    using System.Windows.Forms;    //定义一个接口,用于定义存储过程    interface INorthwindStoredProcedures    {        //定义存储过程对应的方法        DataSet CustOrderHist(string CustomerID);        //如果储存过程名字和方法名字不同,应该用SqlAccessAttribute来进行说明        [SqlAccess("Employee Sales By Country")]        DataTable EmployeeSalesByCountry(DateTime Beginning_Date,DateTime Ending_Date);        //more        //MORE Ideas..        //直接执行SQL语句?        //[SqlAccess(SqlAccessType.SqlQuery,"SELECT * FROM Employees WHERE EmployeeID=@EmpId")]        //DataTable SelectEmployee(int EmpId);    }    class ConsoleApplication    {        [STAThread]        static void Main(string[] args)        {            using(SqlConnection conn=new SqlConnection("server=(local);trusted_connection=true;database=northwind"))            {                //一句话就把实现创建了!                //需要传如 SqlConnection 和 SqlTransaction                //SqlTransaction可以为null                //这个好就好在,只要能得到SqlConnection/SqlTransaction就能用这个方法了,所以兼容 Lostinet.Data.SqlScope                INorthwindStoredProcedures nsp=(INorthwindStoredProcedures)                    StoredProcedure.CreateStoredProcedureInterface(typeof(INorthwindStoredProcedures),conn,null);                //调用储存过程并且显示                ShowData("CustOrderHist ALFKI",nsp.CustOrderHist("ALFKI"));                ShowData("Employee Sales By Country",nsp.EmployeeSalesByCountry(new DateTime(1998,1,1),new DateTime(1999,1,1)));            }        }        static void ShowData(string title,object data)        {            Form f=new Form();            f.Width=600;            f.Height=480;            f.Text=title;            DataGrid grid=new DataGrid();                        grid.Dock=DockStyle.Fill;            grid.DataSource=data;            f.Controls.Add(grid);            f.ShowDialog();        }    }}//实现方法(不完整)#region //实现方法(不完整)namespace Lostinet.Sample{    using System;    using System.Collections;    using System.Reflection;    using System.Reflection.Emit;    using System.Data;    using System.Data.SqlClient;    //这个类作为实现的基类,    //目的是提供储存 SqlConnection/SqlTransaction 和公用的一些方法    //这个类必须为public,否则无法继承    //但开发者不会显式访问这个类    public class SPInterfaceBase : IDisposable    {        public SPInterfaceBase()        {        }        public void Dispose()        {        }        //CreateStoredProcedureInterface会把相关的值SqlConnection/SqlTransaction存到这里        public SqlConnection connection;        public SqlTransaction transaction;        //创建一个SqlCommand        public SqlCommand CreateCommand(string spname)        {            SqlCommand cmd=new SqlCommand(spname,connection,transaction);            cmd.CommandType=CommandType.StoredProcedure;            //TODO:            //cmd.Parameters.Add("@ReturnValue",            return cmd;        }        //由 Type 推算出 SqlDbType , 未完成        SqlDbType GetSqlDbType(Type type)        {            //TODO:switch(type)            return SqlDbType.NVarChar;        }        //定义参数        public void DefineParameter(SqlCommand cmd,string name,Type type,ParameterDirection direction)        {            SqlParameter param=new SqlParameter("@"+name,GetSqlDbType(type));            param.Direction=direction;            cmd.Parameters.Add(param);        }        //在SqlCommand执行前设置参数值        public void SetParameter(SqlCommand cmd,string name,object value)        {            cmd.Parameters["@"+name].Value=(value==null?DBNull.Value:value);        }        //在SqlCommand执行后取得参数值        public object GetParameter(SqlCommand cmd,string name)        {            return cmd.Parameters["@"+name].Value;        }        //根据不同的返回值执行不同的操作        public SqlDataReader ExecuteDataReader(SqlCommand cmd)        {            return cmd.ExecuteReader();        }        public object ExecuteScalar(SqlCommand cmd)        {            return cmd.ExecuteScalar();        }        public void ExecuteNonQuery(SqlCommand cmd)        {            cmd.ExecuteNonQuery();        }        public DataSet ExecuteDataSet(SqlCommand cmd)        {            DataSet ds=new DataSet();            using(SqlDataAdapter sda=new SqlDataAdapter(cmd))            {                sda.Fill(ds);            }            return ds;        }        public DataTable ExecuteDataTable(SqlCommand cmd)        {            DataTable table=new DataTable();            using(SqlDataAdapter sda=new SqlDataAdapter(cmd))            {                sda.Fill(table);            }            return table;        }        public DataRow ExecuteDataRow(SqlCommand cmd)        {            DataTable table=ExecuteDataTable(cmd);            if(table.Rows.Count==0)                return null;            return table.Rows[0];        }    }    public class StoredProcedure    {        static public object CreateStoredProcedureInterface(Type interfaceType,SqlConnection connection,SqlTransaction transaction)        {            //检查参数            if(interfaceType==null)throw(new ArgumentNullException("interfaceType"));            if(!interfaceType.IsInterface)     &nbs