今天在調試代碼的時候突然拋出了如下異常:“XORM.Database”的類型初始值設定項引發異常。
頓時感覺很突兀,平常的時候一點問題沒有,為什么今天調試就出問題了呢?測試了一下,發現在數據處理層的一條實例化代碼處出錯:
//獲取類型的映射信息 MappingInfo mapInfo = xmlMapping.GetDataMapInfo(type); Database db = new Database();//出錯代碼 db.CommandText = storageprocedure; //獲取查詢條件的映射信息
找了很久沒有找到原因,后再網上搜索了下,是因為靜態成員初始化異常引起的問題。我的Database類中只有一個靜態成員。Database類如下:
using System; using System.Collections.Generic; using System.Text; using System.Data.SqlClient; using System.Data; using System.Collections; using System.Configuration; namespace XORM { internal class Database: IDisposable { private static string _connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["TestForCSSConn"].ConnectionString;//靜態成員 private IDbConnection _connection = null; private string _commandText = null; private ArrayList _parameters = new ArrayList(); private bool _disposed; public IDataReader GetDataReader() { using (IDbCommand cmd = getCommand()) { return cmd.ExecuteReader(); } } private ArrayList _inoutParameters = new ArrayList(); private IDbCommand getCommand() { IDbCommand cmd = connection.CreateCommand(); cmd.CommandText = _commandText; cmd.CommandType = CommandType.StoredProcedure; foreach (SqlParameter parm in _parameters) { cmd.Parameters.Add(parm); } //既能輸入也能返回的參數 foreach (SqlParameter parm in _inoutParameters) { parm.Direction = ParameterDirection.Output; cmd.Parameters.Add(parm); } return cmd; } public IDbCommand GetCommand() { return getCommand(); } public string CommandText { set { _commandText = value; } get { return _commandText; } } private IDbConnection connection { get { if (_connection == null) { _connection = new SqlConnection(_connectionString); _connection.Open(); } return _connection; } } public void AddParameters(string name, object obj) { if (name.StartsWith("@") == false) { name = "@" + name; } SqlParameter p = new SqlParameter(name, obj); _parameters.Add(p); } public void AddInOutParameters(string name, object obj) { if (name.StartsWith("@") == false) { name = "@" + name; } SqlParameter p = new SqlParameter(name, obj); _inoutParameters.Add(p); } public ArrayList Parameters { get { return _parameters; } } public void Dispose() { if (_disposed == true) { return; } // Dispose and close the connection Close(); // This object will be cleaned up by the Dispose method. // Therefore, you should call GC.SupressFinalize to // take this object off the finalization queue // and prevent finalization code for this object // from executing a second time. GC.SuppressFinalize(this); _disposed = true; } public void Close() { if (_disposed == true) { return; } if (_connection != null) { _connection.Close(); _connection.Dispose(); } } } }
仔細對比了一下,發現確實是這條語句出了問題,在我的web.config配置文件中數據庫連接字符串的沒有名為TestForCSSConn的,這是因為今天修改了web.config文件,新的數據庫連接字段如下:
<add name="TestForCSS" connectionString="Server=(local);Database=BookExchange;User ID=sa;Password=123;Connection TimeOut=180" providerName="System.Data.SqlClient"/>
將此處的name="TestForCSS"修改為name="TestForCSSConn"就可以了。
通過在網上搜索歸納了一下可能的原因:
1. 訪問類的某一靜態成員,而其他靜態成員的初始化(或靜態構造函數)中產生異常。例如訪問ClassHelper.StaticString,由於靜態成員Field的初始化產生異常,因此調用ClassHelper.StaticString會拋出TypeInitializationException。
2. 訪問類的某一靜態成員,該靜態成員的初始化(或靜態構造函數)中產生異常。
3. 對該類進行初始化,而類中的某個靜態成員初始化(或靜態構造函數)中產生異常。
解決辦法:
1、檢查類中的靜態字段或屬性,確保其能夠正常的完成初始化
2、在類的構造函數中,確保其訪問的屬性或字段都已經完成初始化
3、如果是WinForm中,將訪問的窗體控件的語句寫在初始化方法之后
同時,導致錯誤發生還可能是導入的引用sqlite.dll上,以下是這種情況的解決辦法(引用自博友雪庭):
sqlite.dll分32位和 64位,以前用在32位下,開發換到win 7/x64下。在項目屬性中,修改目平台,從Any CPU改為x86,重新運行正 常,sqlite.dll是32位的,但目標 平台是x64的,有關sqlite的靜態變量初始化異常,引起sqlite類初始化錯誤,引發 TypeInitializationException異常。