2013-03-04 46 views
6

我已經使用反射在.NET應用程序中加載了幾個強類型的數據表,我寫了一個方法。如果我按照下面的方式運行,那麼一切正常 - 包括沒有拋出的異常。但是,如果我使用註釋部分,而不是(其他所有內容相同),那麼我得到未能啓用約束錯誤在此處描述:enter link description hereDataTable load()約束錯誤

如果我看看是什麼錯誤數組裏面,它總是如下:

"Column 'AEDelegateName' does not allow DBNull.Value." 

和ItemArray的錯誤看起來像:

[0] = {} 
[1] = "Some Value" 

這讓我吃驚,因爲我只希望腳本中的1列可以選擇1列,而不是像上面指出的那樣2。我也想象這是接近這個問題,因爲其中一個看起來是空的。

我的腳本不會返回null,我可以快速直觀地確認它,以及在我使用的查詢中說出諸如NOT NULL之類的內容。

private void GetData(string query, Component tableAdapter) 
{ 
    OracleCommand command = new OracleCommand(); 
    command.Connection = conn; 
    command.CommandText = query; 
    command.CommandType = CommandType.Text; 
    command.CommandTimeout = 3000; 
    OracleDataReader reader = command.ExecuteReader(CommandBehavior.SingleResult); 
    MethodInfo[] methods = tableAdapter.GetType().GetMethods(); 
    MethodInfo getDataMethod = tableAdapter.GetType().GetMethod("GetData"); 
    DataTable table = (DataTable)getDataMethod.Invoke(tableAdapter, null); 
    Type[] paramTypes = new Type[] { table.GetType() }; 
    MethodInfo updateMethod = tableAdapter.GetType().GetMethod("Update", paramTypes); 
    foreach (DataRow row in table.Rows) 
    { 
     row.Delete(); 
    } 
    //try 
    //{ 
    // if (reader.HasRows) 
    // { 
    //  table.Load(reader, LoadOption.OverwriteChanges, FillErrorHandler); 
    // } 
    //} 
    //catch (Exception e) 
    //{ 
    // DataRow[] errors = table.GetErrors(); 
    //} 
    while (reader.Read()) 
    { 
     try 
     { 
      List<object> newRow = new List<object>(); 
      for (int i = 0; i < reader.FieldCount; ++i) 
      { 
       object currentValue = reader.GetValue(i); 
       Debug.WriteLine("Value: "+currentValue); 
       newRow.Add(currentValue); 
      } 
      table.Rows.Add(newRow.ToArray()); 
     } 
     catch (ConstraintException e) 
     { 
      DataRow[] errors = table.GetErrors(); 
     } 
    }    
    updateMethod.Invoke(tableAdapter, new object[]{table}); 
    reader.Close(); 
} 
+0

你能描述'DataTable表'和通過'OracleDataReader'運行的查詢之間的關係嗎?我感覺兩者的模式都不相同,DataTable.Load()覆蓋了定義,從而觸發了約束。 – Caramiriel 2013-03-13 21:45:35

+0

哪個'catch'塊正在捕捉? – radarbob 2013-03-13 22:00:53

+0

.... @ Caramiriel可能是在正確的軌道上,但我會採取一個受過教育的WAG,並建議在行刪除循環後添加'AcceptChanges()'。 – radarbob 2013-03-13 22:10:38

回答

1

根據DataTable.Load Method (IDataReader, LoadOption)的文檔,我懷疑您可能遇到以下摘錄中描述的行爲。你檢查過你的查詢返回的列數與DataTable的列數嗎?從查詢返回的列的名稱是否與DataTable中的所需列名稱匹配?

條件:的架構兼容,但加載結果集架構包含比該數據表更少的列。

行爲:如果缺少列定義了缺省值或列的數據類型是可空的,Load方法允許行是 添加,代替缺少的列的默認值或空值。 如果不能使用默認值或null,則Load方法會拋出 異常。如果沒有提供特定的默認值,則加載 方法使用空值作爲隱含的默認值。

您在while循環中的代碼可能工作,因爲它不會嘗試匹配模式。它只是在位置上填充值,並且只要類型兼容,不會違反約束條件,並且該數組不包含更多的項目而不是包含行的列。