2008-09-26 17 views
31

如何找出哪個列和值違反約束?例外消息根本沒有幫助:加載DataSet時觸發ConstraintException的是什麼?

無法啓用約束。一個或多個行包含違反 非空,唯一或外鍵 約束的值。

+2

我願意給你更多的了贊成票,如果我能。這也是我身邊的一根刺。 – 2008-09-26 15:19:56

回答

20

和許多人一樣,我有自己的標準的數據訪問組件,其中包括方法返回一個DataSet。當然,如果拋出ConstraintException,DataSet不會返回給調用者,因此調用者無法檢查行錯誤。

我做了什麼是漁獲物和重新拋出ConstraintException在這種方法中,記錄行錯誤的詳細信息,如下面的例子(使用log4net的日誌記錄):

... 
try 
{ 
    adapter.Fill(dataTable); // or dataSet 
} 
catch (ConstraintException) 
{ 
    LogErrors(dataTable); 
    throw; 
} 
... 

private static void LogErrors(DataSet dataSet) 
{ 
    foreach (DataTable dataTable in dataSet.Tables) 
    { 
     LogErrors(dataTable); 
    } 
} 

private static void LogErrors(DataTable dataTable) 
{ 
    if (!dataTable.HasErrors) return; 
    StringBuilder sb = new StringBuilder(); 
    sb.AppendFormat(
     CultureInfo.CurrentCulture, 
     "ConstraintException while filling {0}", 
     dataTable.TableName); 
    DataRow[] errorRows = dataTable.GetErrors(); 
    for (int i = 0; (i < MAX_ERRORS_TO_LOG) && (i < errorRows.Length); i++) 
    { 
     sb.AppendLine(); 
     sb.Append(errorRows[i].RowError); 
    } 
    _logger.Error(sb.ToString()); 
} 
+0

您的LogErrors方法非常棒!今天從字面上救了我。 – Dave 2010-04-14 22:36:55

1

我添加了一些代碼,我我發現在調試ConstraintException發生時很有用here

希望這會有所幫助。

3

當您使用強類型數據集和使用的可視化設計器(XSD):訪問tbl.Rows [0] .RowError信息,你需要創建填寫方法。

您的不能使用Get方法,因爲DataTable是在生成的代碼中實例化的。

+0

像你說的,你需要填寫。很奇怪;爲什麼我只需要獲取一些數據(基本選擇)就需要填充語句。似乎在裏面的某個地方這個Fill方法被.net使用。在我生成一個填充方法(沒有改變得到)它的工作。 – Obelix 2013-12-30 14:29:12

1

誰想要一個片段就要上ConstraintException更多細節的Google:

try 
{ 
    ds.EnforceConstraints = true; 
} 
catch (ConstraintException ex) 
{ 
    string details = string.Join("", 
     ds.Tables.Cast<DataTable>() 
      .Where(t => t.HasErrors) 
      .SelectMany(t => t.GetErrors()) 
      .Take(50) 
      .Select(r => "\n - " + r.Table.TableName + "[" + string.Join(", ", r.Table.PrimaryKey.Select(c => r[c])) + "]: " + r.RowError)); 
    throw new ConstraintException(ex.Message + details); 
} 
相關問題