源码调试Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
2011-12-03 08:35 symphony2010 阅读(575) 评论(0) 编辑 收藏 举报
单步调试分析错误:
抛出异常时,断下。
发现在此方法中抛出异常:
函数位置:System.Data.dll!System.Data.DataTable.EnableConstraints()
internal void EnableConstraints()
{
bool flag = false;
foreach (Constraint constraint in this.Constraints)
{
if (constraint is UniqueConstraint)
{
flag |= constraint.IsConstraintViolated();
}
}
foreach (DataColumn column in this.Columns)
{
if (!column.AllowDBNull)
{
flag |= column.IsNotAllowDBNullViolated();
}
if (column.MaxLength >= 0)
{
flag |= column.IsMaxLengthViolated();
}
}
if (flag)
{
this.EnforceConstraints = false;
throw ExceptionBuilder.EnforceConstraint();//抛出异常页面
}
}
在以上方法的foreach循环里面,当column 为“postId”时,column.IsNotAllowDBNullViolated(),为true,导致抛出异常。换句话说 ,就是违反了column不能为空的约束。
单步进入column.IsNotAllowDBNullViolated():
函数位置: System.Data.dll!System.Data.DataColumn.IsNotAllowDBNullViolated()
internal bool IsNotAllowDBNullViolated()
{
Index sortIndex = this.SortIndex;
DataRow[] rows = sortIndex.GetRows(sortIndex.FindRecords(DBNull.Value));
for (int i = 0; i < rows.Length; i++)
{
string error = ExceptionBuilder.NotAllowDBNullViolationText(this.ColumnName);//这里已经报出出错提示
,但是没有在最后抛出,最后抛出的是一个刚含糊的异常"Column 'PostId' does not allow DBNull.Value."
rows[i].RowError = error;
rows[i].SetColumnError(this, error);
}
return (rows.Length > 0);
}
问题是我在数据库里PostId是主键,而且不允许为空啊?探索继续……
internal bool EnforceConstraints
{
get
{
if (this.SuspendEnforceConstraints)
{
return false;
}
if (this.dataSet != null)
{
return this.dataSet.EnforceConstraints;
}
return this.enforceConstraints;
}
set
{
if ((this.dataSet == null) && (this.enforceConstraints != value))
{
if (value)
{
this.EnableConstraints();
}
this.enforceConstraints = value;
}
}
}
查看我配置的强类型的DataSet语句:
改成 select PostId,UserId ,PostTime,PostContent,PostTitle from PostInfo where userId=@userId ,解决问题!!去掉userId的话也不会报错。
总结如下:
添加查询语句时要至少选出主键,因为在填充 DataTable,没有主 键会触发主键不允许为空约束。