分享+开源:持久性数据访问层

微软的DAAB(现在叫Enterprise Library了)cache了stored procedure的parameter list,但是,实现一个功能完整的O/R mapping,还需要扩充到对数据库结构的cache,这样才能创建dynamic sql commands。

网上没有找到合适的代码,就自己写了一个,根据连接字符串,cache相应数据库,不过目前只做了工作中用到的部分,即Sql Server的table和column。

分享一下,也希望大家来完善它,方便我们的工作。若有意共享代码请赐函amy_seahawk@yahoo.com(也是msn),谢谢。

代码如下:

using System.Collections;

using System.ComponentModel;
      
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;

using System.Reflection;

using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.SessionState;

namespace Athos.Data
{
  
  #region class SpiColumn
  public class SpiColumn: IStateManager
  {
    private bool marked;
    private SpiTable table;
    private StateBag statebag;
    protected StateBag ViewState 
    {
      get
      {
        return this.statebag; 
      } 
    }


    #region IStateManager
    public bool IsTrackingViewState 
    {
      get
      {
        return this.marked;
      }
    }


    void System.Web.UI.IStateManager.LoadViewState(object state)
    {
      this.LoadViewState(state); 
    } 

    protected virtual void LoadViewState(object savedState)
    {
      object[] arrViewState;
      if (savedState != null)
      {
        arrViewState = ((object[]) savedState);
        if (arrViewState[0] != null)
        {
          ((IStateManager)ViewState).LoadViewState(arrViewState[0]); 
        }
      } 
    }


    object System.Web.UI.IStateManager.SaveViewState()
    {
      return this.SaveViewState(); 
    }
    public virtual object SaveViewState()
    {
      object obj1;
      object[] arrViewState;
      obj1 = ((IStateManager)ViewState).SaveViewState();
      if (obj1 != null) 
      {
        arrViewState = new object[1];
        arrViewState[0] = obj1;
        return arrViewState; 
      }
      return null; 
    } 


    void System.Web.UI.IStateManager.TrackViewState()
    {
      this.TrackViewState(); 
    }
    public virtual void TrackViewState()
    {
      this.marked = true;
      ((IStateManager)ViewState).TrackViewState(); 
    } 

    #endregion

    public SpiColumn()
    {
      this.statebag = new StateBag();
    }

    internal void SetTable(SpiTable table)
    {
      this.table = table;
    } 


    #region Column properties from SQL Database
    private string m_Description;
    public string Description 
    { 
      get 
      {
        return m_Description;
      }
      set
      {
        m_Description=value;
      }
    }

    private string m_defaultValue;
    public string DefaultValue 
    { 
      get 
      {
        return m_defaultValue;
      }
      set
      {
        m_defaultValue=value;
      }
    }


    private int m_identityseed;
    public int IdentitySeed
    { 
      get 
      {
        return m_identityseed;
      }
      set
      {
        m_identityseed = value;
      }
    }

    private int m_identityincrement;
    public int IdentityIncrement
    { 
      get 
      {
        return m_identityincrement;
      }
      set
      {
        m_identityincrement = value;
      }
    }



    private bool m_isidentity;
    public bool IsIdentity
    {
      get
      {
        return m_isidentity;
      }
      set
      {
        m_isidentity = value;
      }
    }
    private bool m_isidnotforrepl;
    public bool IsIDNotForRepl
    {
      get
      {
        return m_isidnotforrepl;
      }
      set
      {
        m_isidnotforrepl = value;
      }
    }
    private bool m_isnullable;
    public bool IsNullAble 
    { 
      get 
      {
        return m_isnullable;
      }
      set
      {
        m_isnullable = value;
      }
    }    

    private bool m_isprimarykey;
    public bool IsPrimaryKey
    { 
      get 
      {
        return m_isprimarykey;
      }
      set
      {
        m_isprimarykey = value;
      }
    }    

    private int m_key_seq;
    public int Key_Seq 
    { 
      get 
      {
        return m_key_seq;
      }
      set
      {
        m_key_seq = value;
      }
    }

    private int m_length;
    public int Length 
    { 
      get 
      {
        return m_length;
      }
      set
      {
        m_length = value;
      }
    }    
    private string m_name;
    public string Name 
    { 
      get 
      {
        return m_name;
      }
      set
      {
        m_name = value;
      }
    }

    private string m_type;
    public string Type 
    { 
      get 
      {
        return m_type;
      }
      set
      {
        m_type = value;
      }
    }

    private int m_xprec;
    public int Xprec 
    { 
      get 
      {
        return m_xprec;
      }
      set
      {
        m_xprec = value;
      }
    }

    private int m_xscale;
    public int Xscale 
    { 
      get 
      {
        return m_xscale;
      }
      set
      {
        m_xscale = value;
      }
    }

    #endregion
  }
 
  #endregion
  #region class SpiColumnCollection
  public sealed class SpiColumnCollection : ICollection, IStateManager
  {
    private SpiTable table;
    private ArrayList columns;
    private bool marked;
    #region .ctor()
    public SpiColumnCollection(SpiTable table, ArrayList columns)
    {
      this.table = table;
      this.columns = columns; 
    }

    #endregion
    #region properties
    #region  ICollection: Count
    public int Count 
    { 
      get
      {
        return this.columns.Count; 
      }
    }
    #endregion
    public bool IsReadOnly 
    { 
      get
      {
        return false;
      }
    }
    #region  ICollection: IsSynchronized
    public bool IsSynchronized
    { 
      get
      {
        return false;
      }
    }
    #endregion
    public SpiColumn this[int index] 
    { 
      get
      {
        return ((SpiColumn) this.columns[index]); 
      } 
    }
    internal int indexof(string columnname)
    {
      for(int i=0;i<this.columns.Count;i++)
      {
        if(((SpiColumn) columns[i]).Name == columnname)
          return i;
      }
      return -1;
    }
    public SpiColumn this[String columnname] 
    { 
      get
      {
        int columnindex = indexof(columnname);
        if (columnindex < 0)
          return null;
        else
          return ((SpiColumn) this.columns[columnindex]); 
      } 
    }
    #region ICollection: SyncRoot
    public object SyncRoot 
    { 
      get
      {
        return this; 
      } 
    }

    #endregion 

    #region  IStateManager: LoadViewState/SaveViewState/TrackViewState/IsTrackingViewState
    bool System.Web.UI.IStateManager.IsTrackingViewState 
    {
      get
      {
        return this.marked; 
      }
    }
 
    #endregion

    #endregion 


    public void Add(SpiColumn column)
    {
      this.AddAt(-1, column);
 
    }
    public void AddAt(int index, SpiColumn column)
    {
      if (index == -1)
      {
        this.columns.Add(column); 
      }
      else
      {
        this.columns.Insert(index, column); 
      }
      column.SetTable(this.table);
      if (this.marked)
      {
        column.TrackViewState(); 
      } 
    }
    public void Clear()
    {
      this.columns.Clear(); 
    }
    #region ICollection: SyncRoot
    public void CopyTo(Array array, int index)
    {
      IEnumerator enumerator1;
      enumerator1 = this.GetEnumerator();
      while (enumerator1.MoveNext())
      {
        index = (index + 1);
        array.SetValue(enumerator1.Current, index); 
      } 
    }
    #endregion
    #region  IStateManager: LoadViewState/SaveViewState/TrackViewState/IsTrackingViewState
    void System.Web.UI.IStateManager.LoadViewState(object state)
    {
      object[] arrViewState;
      int i;
      if (state != null)
      {
        arrViewState = ((object[]) state);
        if (arrViewState.Length == this.columns.Count)
        {
          for (i = 0; (i < arrViewState.Length); i = (i + 1))
          {
            if (arrViewState[i] != null)
            {
              ((IStateManager) this.columns[i]).LoadViewState(arrViewState[i]); 
            } 
          } 
        } 
      } 
    }
    object System.Web.UI.IStateManager.SaveViewState()
    {
      int intCount;
      object[] arrViewState;
      bool blOK;
      int i;

      intCount = this.columns.Count;
      arrViewState = new object[((uint) intCount)];
      blOK = false;
      for (i = 0; (i < intCount); i++)
      {
        arrViewState[i] = ((IStateManager) this.columns[i]).SaveViewState();
        if (arrViewState[i] != null)
        {
          blOK = true; 
        } 
      }
      if (!blOK)
      {
        return null; 
      }
      return arrViewState; 
    }
    void System.Web.UI.IStateManager.TrackViewState()
    {
      int intCount;
      int i;
      this.marked = true;
      intCount = this.columns.Count;
      for (i = 0; (i < intCount); i = (i + 1))
      {
        ((IStateManager) this.columns[i]).TrackViewState(); 
      } 
    }
    
    #endregion
    #region IEnumerable: GetEnumerator
    public IEnumerator GetEnumerator()
    {
      return this.columns.GetEnumerator(); 
    }
    #endregion 
    public int IndexOf(SpiColumn column)
    {
      if (column != null)
      {
        return this.columns.IndexOf(column); 
      }
      return -1; 
    }
    public void Remove(SpiColumn column)
    {
      int num1;
      num1 = this.IndexOf(column);
      if (num1 >= 0)
      {
        this.RemoveAt(num1);
 
      }
 
    }
    public void RemoveAt(int index)
    {
      if ((index >= 0) && (index < this.Count))
      {
        this.columns.RemoveAt(index);
        
        return; 
      }
      throw new ArgumentOutOfRangeException("index");
 
    }

    
    
  }
 
  #endregion
  #region class SpiTable
  public class SpiTable: IStateManager
  {    

    #region  properties
    
    private bool marked;
    private string tablename;
    public String TableName
    {
      get
      {
        return tablename;
      }
      set
      {
        tablename = value;
      }
    }
    private int keycount;
    public int KeyCount
    {
      get
      {
        return keycount;
      }
      set
      {
        keycount = value;
      }
    }
    private StateBag statebag;
    protected StateBag ViewState 
    {
      get
      {
        return this.statebag; 
      } 
    }

    #endregion

    public SpiTable(String tablename)
    {
      this.statebag = new StateBag();
      this.tablename = tablename;
    }  
    #region IStateManager
    public bool IsTrackingViewState 
    {
      get
      {
        return this.marked;
      }
    }


    void System.Web.UI.IStateManager.LoadViewState(object state)
    {
      this.LoadViewState(state); 
    } 

    protected virtual void LoadViewState(object savedState)
    {
      object[] arrViewState;
      if (savedState != null)
      {
        arrViewState = ((object[]) savedState);
        if (arrViewState[0] != null)
        {
          ((IStateManager)ViewState).LoadViewState(arrViewState[0]); 
        }
      } 
    }


    object System.Web.UI.IStateManager.SaveViewState()
    {
      return this.SaveViewState(); 
    }
    public virtual object SaveViewState()
    {
      object obj1;
      object[] arrViewState;
      obj1 = ((IStateManager)ViewState).SaveViewState();
      if (obj1 != null) 
      {
        arrViewState = new object[1];
        arrViewState[0] = obj1;
        return arrViewState; 
      }
      return null; 
    } 


    void System.Web.UI.IStateManager.TrackViewState()
    {
      this.TrackViewState(); 
    }
    public virtual void TrackViewState()
    {
      this.marked = true;
      ((IStateManager)ViewState).TrackViewState(); 
    } 

    #endregion


    private SpiDatabase database;
    internal void SetDatabase(SpiDatabase database)
    {
      this.database = database;
    } 


    private SpiColumnCollection ColumnsCollection;
    private ArrayList fields;

    public virtual SpiColumnCollection Columns 
    {
      get
      {
        if (this.ColumnsCollection == null)
        {
          this.fields = new ArrayList();
          this.ColumnsCollection = new SpiColumnCollection(this, this.fields);
          if (true) //athos: later need to change to if(base.IsTrackingViewState)...
          {
            ((IStateManager)ColumnsCollection).TrackViewState(); 
          } 
        }
        return this.ColumnsCollection; 
      }
    }
 

    /// <summary>
    /// Resolve at run time the appropriate set of SqlParameters for a stored procedure
    /// </summary>
    /// <param name="connection">A valid SqlConnection object</param>
    /// <param name="spName">The name of the stored procedure</param>
    /// <param name="includeReturnValueParameter">Whether or not to include their return value parameter</param>
    /// <returns>The parameter array discovered.</returns>
    public void DiscoverTableSchema()
    {
      #region get column list
      DataSet dsColumnList = Athos.Data.SqlHelper.ExecuteDataset
        (
        database.ConnectionString, CommandType.Text,
        string.Concat
        (
        @"SELECT c.[id], c.colid, c.[name], t.[name] type, c.length, c.isnullable, c.xprec, c.xscale, 
(select m.[text] from dbo.syscomments m where m.[id]=c.cdefault) defaultvalue,
(select p.[value] from dbo.sysproperties p where p.id=c.id and p.smallid=c.colid) description
FROM dbo.syscolumns c, dbo.systypes t
WHERE 
(c.id = OBJECT_ID('",
        TableName,
        @"')) AND (c.name <> 'dtproperties') 
AND c.xusertype = t.xusertype
ORDER BY c.colid"

        )
        );
      SpiColumn column;
      foreach(DataRow dr in  dsColumnList.Tables[0].Rows)
      {
        column = new SpiColumn();
        Columns.Add(column);
        column.DefaultValue = dr["defaultvalue"].ToString();
        column.Description = dr["description"].ToString();
        column.IsNullAble = Convert.ToBoolean(dr["isnullable"]);
        column.Length = Convert.ToInt32(dr["length"]);
        column.Name = dr["name"].ToString();
        column.Type = dr["type"].ToString();
        column.Xprec = Convert.ToInt32(dr["xprec"]);
        column.Xscale = Convert.ToInt32(dr["xscale"]);
      }
      #endregion
      #region get primary keys
      DataSet dsPKeys = Athos.Data.SqlHelper.ExecuteDataset
        (
        database.ConnectionString, CommandType.Text,
        string.Concat("sp_pkeys '", TableName, "'")
        );
      String strColName; 
      foreach(DataRow dr in dsPKeys.Tables[0].Rows)
      {
        strColName = dr["COLUMN_NAME"].ToString();
        foreach(SpiColumn col in Columns)
        {
          if(col.Name == strColName)
          {
            col.IsPrimaryKey = true;
            col.Key_Seq = Convert.ToInt32(dr["KEY_SEQ"]);
          }
        }
      }
      this.KeyCount = dsPKeys.Tables[0].Rows.Count;
      #endregion
      #region get identity column, if any
      DataSet dsIdentity = Athos.Data.SqlHelper.ExecuteDataset
        (
        database.ConnectionString, CommandType.Text,
        string.Concat(
        @"declare  @objname as nvarchar(776) 
set @objname = '",
        TableName, 
        @"'

declare @objid int
select @objid = id from sysobjects where id = object_id(@objname)

declare @colname sysname
select @colname = name from syscolumns where id = @objid and colstat & 1 = 1
    
select
'Identity' = isnull(@colname,'No identity column defined.'),
'IdentitySeed' = ident_seed(@objname),
'IdentityIncrement' = ident_incr(@objname),
'NotForReplication'  = ColumnProperty(@objid, @colname, 'IsIDNotForRepl')"
        )
        );
      
      String strIdentityCol = dsIdentity.Tables[0].Rows[0]["Identity"].ToString();
      if(strIdentityCol != "No identity column defined.")
      {
        foreach(SpiColumn col in Columns)
        {
          if(col.Name == strIdentityCol)
          {
            col.IsIdentity = true;
            col.IdentityIncrement = 
              Convert.ToInt32(dsIdentity.Tables[0].Rows[0]["IdentityIncrement"]);
            col.IdentitySeed = 
              Convert.ToInt32(dsIdentity.Tables[0].Rows[0]["IdentitySeed"]);
            col.IsIDNotForRepl =
              (Convert.ToInt32(dsIdentity.Tables[0].Rows[0]["NotForReplication"])==1);
          }
        }
      }
      #endregion
    }


  }
  #endregion
  #region class SpiTableCollection
  public sealed class SpiTableCollection : ICollection, IStateManager
  {
    private SpiDatabase database;
    private ArrayList tables;
    private bool marked;

    #region .ctor()
    public SpiTableCollection(SpiDatabase database, ArrayList tables)
    {
      this.database = database;
      this.tables = tables; 
    }

    #endregion
    #region properties
    #region  ICollection: Count
    public int Count 
    { 
      get
      {
        return this.tables.Count; 
      }
    }
    #endregion
    public bool IsReadOnly 
    { 
      get
      {
        return false;
      }
    }
    #region  ICollection: IsSynchronized
    public bool IsSynchronized
    { 
      get
      {
        return false;
      }
    }
    #endregion
    public SpiTable this[int index] 
    { 
      get
      {
        return ((SpiTable) this.tables[index]); 
      } 
    }
    internal int indexof(string tablename)
    {
      for(int i=0;i<this.tables.Count;i++)
      {
        if(((SpiTable) tables[i]).TableName == tablename)
          return i;
      }
      return -1;
    }
    public SpiTable this[String tablename] 
    { 
      get
      {
        int tableindex = indexof(tablename);
        if (tableindex < 0)
          return null;
        else
          return ((SpiTable) this.tables[tableindex]); 
      } 
    }
    #region ICollection: SyncRoot
    public object SyncRoot 
    { 
      get
      {
        return this; 
      } 
    }

    #endregion 

    #region  IStateManager: LoadViewState/SaveViewState/TrackViewState/IsTrackingViewState
    bool System.Web.UI.IStateManager.IsTrackingViewState 
    {
      get
      {
        return this.marked; 
      }
    }
 
    #endregion

    #endregion 


    public void Add(SpiTable table)
    {
      this.AddAt(-1, table);
 
    }
    public void AddAt(int index, SpiTable table)
    {
      if (index == -1)
      {
        this.tables.Add(table); 
      }
      else
      {
        this.tables.Insert(index, table); 
      }
      table.SetDatabase(this.database);
      if (this.marked)
      {
        table.TrackViewState(); 
      } 
    }
    public void Clear()
    {
      this.tables.Clear(); 
    }
    #region ICollection: SyncRoot
    public void CopyTo(Array array, int index)
    {
      IEnumerator enumerator1;
      enumerator1 = this.GetEnumerator();
      while (enumerator1.MoveNext())
      {
        index = (index + 1);
        array.SetValue(enumerator1.Current, index); 
      } 
    }
    #endregion
    #region  IStateManager: LoadViewState/SaveViewState/TrackViewState/IsTrackingViewState
    void System.Web.UI.IStateManager.LoadViewState(object state)
    {
      object[] arrViewState;
      int i;
      if (state != null)
      {
        arrViewState = ((object[]) state);
        if (arrViewState.Length == this.tables.Count)
        {
          for (i = 0; (i < arrViewState.Length); i = (i + 1))
          {
            if (arrViewState[i] != null)
            {
              ((IStateManager) this.tables[i]).LoadViewState(arrViewState[i]); 
            } 
          } 
        } 
      } 
    }
    object System.Web.UI.IStateManager.SaveViewState()
    {
      int intCount;
      object[] arrViewState;
      bool blOK;
      int i;

      intCount = this.tables.Count;
      arrViewState = new object[((uint) intCount)];
      blOK = false;
      for (i = 0; (i < intCount); i++)
      {
        arrViewState[i] = ((IStateManager) this.tables[i]).SaveViewState();
        if (arrViewState[i] != null)
        {
          blOK = true; 
        } 
      }
      if (!blOK)
      {
        return null; 
      }
      return arrViewState; 
    }
    void System.Web.UI.IStateManager.TrackViewState()
    {
      int intCount;
      int i;
      this.marked = true;
      intCount = this.tables.Count;
      for (i = 0; (i < intCount); i = (i + 1))
      {
        ((IStateManager) this.tables[i]).TrackViewState(); 
      } 
    }
    
    #endregion
    #region IEnumerable: GetEnumerator
    public IEnumerator GetEnumerator()
    {
      return this.tables.GetEnumerator(); 
    }
    #endregion 
    public int IndexOf(SpiTable table)
    {
      if (table != null)
      {
        return this.tables.IndexOf(table); 
      }
      return -1; 
    }
    public void Remove(SpiTable table)
    {
      int num1;
      num1 = this.IndexOf(table);
      if (num1 >= 0)
      {
        this.RemoveAt(num1);
 
      }
 
    }
    public void RemoveAt(int index)
    {
      if ((index >= 0) && (index < this.Count))
      {
        this.tables.RemoveAt(index);
        
        return; 
      }
      throw new ArgumentOutOfRangeException("index");
 
    }

    
    
  }
 
  #endregion
  #region class SpiDatabase
  public class SpiDatabase: IStateManager
  {

    #region  private members: marked, stagebag, ViewState, ConnectionString
    
    private bool marked;

    private StateBag statebag;
    protected StateBag ViewState 
    {
      get
      {
        return this.statebag; 
      } 
    }


    private string connectionstring;
    public String ConnectionString
    {
      get
      {
        return connectionstring;
      }
      set
      {
        connectionstring = value;
      }
    }
    #endregion

    public SpiDatabase(string connectionstring)
    {
      this.statebag = new StateBag();
      this.connectionstring = connectionstring;
    }  
    #region IStateManager
    public bool IsTrackingViewState 
    {
      get
      {
        return this.marked;
      }
    }


    void System.Web.UI.IStateManager.LoadViewState(object state)
    {
      this.LoadViewState(state); 
    } 

    protected virtual void LoadViewState(object savedState)
    {
      object[] arrViewState;
      if (savedState != null)
      {
        arrViewState = ((object[]) savedState);
        if (arrViewState[0] != null)
        {
          ((IStateManager)ViewState).LoadViewState(arrViewState[0]); 
        }
      } 
    }


    object System.Web.UI.IStateManager.SaveViewState()
    {
      return this.SaveViewState(); 
    }
    public virtual object SaveViewState()
    {
      object obj1;
      object[] arrViewState;
      obj1 = ((IStateManager)ViewState).SaveViewState();
      if (obj1 != null) 
      {
        arrViewState = new object[1];
        arrViewState[0] = obj1;
        return arrViewState; 
      }
      return null; 
    } 


    void System.Web.UI.IStateManager.TrackViewState()
    {
      this.TrackViewState(); 
    }
    public virtual void TrackViewState()
    {
      this.marked = true;
      ((IStateManager)ViewState).TrackViewState(); 
    } 

    #endregion


    private SpiDatabase database;
    internal void SetDatabase(SpiDatabase database)
    {
      this.database = database;
    } 


    private SpiTableCollection TablesCollection;
    private ArrayList tables;

    public virtual SpiTableCollection Tables 
    {
      get
      {
        if (this.TablesCollection == null)
        {
          this.tables = new ArrayList();
          this.TablesCollection = new SpiTableCollection(this, this.tables);
          if (true) //athos: later need to change to if(base.IsTrackingViewState)...
          {
            ((IStateManager)TablesCollection).TrackViewState(); 
          } 
        }
        return this.TablesCollection; 
      }
    }
 

  }
  #endregion
  #region class SpiDatabaseCache
  /// <summary>
  /// SpiDatabaseCache provides functions to leverage a static cache of procedure parameters, and the
  /// ability to discover parameters for stored procedures at run-time.
  /// </summary>
  public sealed class SpiDatabaseCache
  {
    #region private methods, variables, and constructors

    //Since this class provides only static methods, make the default constructor private to prevent 
    //instances from being created with "new SpiDatabaseCache()"
    private SpiDatabaseCache() {}

    private static Hashtable schemaCache = Hashtable.Synchronized(new Hashtable());

    public static bool CheckConnectionString(String strConnectionString)
    {
      SqlConnection sqlConn = new SqlConnection(strConnectionString);
      try
      {
        sqlConn.Open();
        sqlConn.Close();
        return true;
      }
      catch(Exception ex)
      {
        String strEx = ex.Message, strEy;
        strEy = strEx;
        strEx = strEy;
        return false;
      }
    }

    /// <summary>
    /// Resolve at run time the appropriate set of SqlParameters for a stored procedure
    /// </summary>
    /// <param name="connection">A valid SqlConnection object</param>
    /// <param name="spName">The name of the stored procedure</param>
    /// <param name="includeReturnValueParameter">Whether or not to include their return value parameter</param>
    /// <returns>The parameter array discovered.</returns>
    public static SpiDatabase DiscoverDatabaseSchema(SqlConnection sqlConn)
    {
      SpiDatabase database = new SpiDatabase(sqlConn.ConnectionString);

      DataSet dsTableList = Athos.Data.SqlHelper.ExecuteDataset(sqlConn, CommandType.Text,
        "SELECT name FROM sysobjects WHERE xtype='u' and name<>'dtproperties' ORDER BY name");
      String strTableName = "";
      SpiTable table;

      foreach(DataRow dr in  dsTableList.Tables[0].Rows)
      {
        strTableName = dr["name"].ToString();
        table = new SpiTable(strTableName);
        database.Tables.Add(table);
        table.DiscoverTableSchema();
      }

      return database;
    }


    #endregion private methods, variables, and constructors

    #region caching functions

    /// <summary>
    /// Add Database Schema to the cache
    /// </summary>
    /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    /// <param name="dsDatabaseSchema">A Database containing Database schema</param>
    public static void CacheDatabaseSchema(string connectionString, SpiDatabase dsDatabaseSchema)
    {
      if( connectionString == null || connectionString.Length == 0 ) 
        throw new ArgumentNullException( "connectionString" );
      string hashKey = connectionString;
      schemaCache[hashKey] = dsDatabaseSchema;
    }

    /// <summary>
    /// Retrieve a parameter array from the cache
    /// </summary>
    /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    /// <param name="commandText">The stored procedure name or T-SQL command</param>
    /// <returns>An array of SqlParamters</returns>
    public static SpiDatabase GetCachedDatabaseSchema(string connectionString)
    {
      if( connectionString == null || connectionString.Length == 0 ) 
        throw new ArgumentNullException( "connectionString" );
      
      string hashKey = connectionString ;
      SpiDatabase cachedDatabaseSchema = schemaCache[hashKey] as SpiDatabase;
      if (cachedDatabaseSchema == null)
      {  
        return null;
      }
      else
      {          
        return (cachedDatabaseSchema);
      }
    }

    #endregion caching functions

    #region Database Schema Discovery Functions

    /// <summary>
    /// Retrieves the Database Schema 
    /// </summary>
    /// <remarks>
    /// This method will query the database for this information, and then store it in a cache for future requests.
    /// </remarks>
    /// <param name="connectionString">A valid connection string for a SqlConnection</param>
    /// <returns>An DataSet showing Database Schema</returns>
    public static SpiDatabase GetDatabaseSchema(string connectionString)
    {
      if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" );

      using(SqlConnection connection = new SqlConnection(connectionString))
      {
        return GetDatabaseSchemaInternal(connection);
      }
    }

    /// <summary>
    /// Retrieves the set of SqlParameters appropriate for the stored procedure
    /// </summary>
    /// <remarks>
    /// This method will query the database for this information, and then store it in a cache for future requests.
    /// </remarks>
    /// <param name="connection">A valid SqlConnection object</param>
    /// <param name="spName">The name of the stored procedure</param>
    /// <returns>An array of SqlParameters</returns>
    internal static SpiDatabase GetDatabaseSchema(SqlConnection connection)
    {
      if( connection == null ) throw new ArgumentNullException( "connection" );
      using (SqlConnection clonedConnection = (SqlConnection)((ICloneable)connection).Clone())
      {
        return GetDatabaseSchemaInternal(clonedConnection);
      }
    }

    /// <summary>
    /// Retrieves the DataSet of Database Schema appropriate
    /// </summary>
    /// <param name="connection">A valid SqlConnection object</param>
    /// <returns>An DataSet of Database Schema</returns>
    private static SpiDatabase GetDatabaseSchemaInternal(SqlConnection connection)
    {
      if( connection == null ) throw new ArgumentNullException( "connection" );

      string hashKey = connection.ConnectionString;

      SpiDatabase cachedDatabaseSchema;
          
      cachedDatabaseSchema = schemaCache[hashKey] as SpiDatabase;
      if (cachedDatabaseSchema == null)
      {  
        SpiDatabase dsDatabaseSchema = DiscoverDatabaseSchema(connection);
        schemaCache[hashKey] = dsDatabaseSchema;
        cachedDatabaseSchema = dsDatabaseSchema;
      }
          
      return cachedDatabaseSchema;
    }
        
    #endregion Database Schema Discovery Functions

  }
  #endregionusing System;

}


athossmth原创,转载请注明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值