代码改变世界

源码调试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."

,但是没有在最后抛出,最后抛出的是一个刚含糊的异常"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语句:

image

改成 select PostId,UserId ,PostTime,PostContent,PostTitle from PostInfo where userId=@userId ,解决问题!!去掉userId的话也不会报错。

总结如下:

添加查询语句时要至少选出主键,因为在填充 DataTable,没有主 键会触发主键不允许为空约束。