【问题标题】:SqlDataAdapter Fill gives NULL primary keysSqlDataAdapter Fill 给出 NULL 主键
【发布时间】:2015-01-07 20:03:22
【问题描述】:

所以我有点头疼,我正在寻求帮助。我们最近将 ASP.Net Web 表单应用程序从 .Net 3.5、Win 2003 和 SQL 2008 迁移到 .Net 4.5、Win 2008 和 SQL 2012。该应用程序在旧平台上运行了 4 年以上,没有任何问题。在新平台上,我们遇到了导致其崩溃的间歇性问题。我们添加了错误捕获,以隔离问题发生的确切位置以及我们所看到的没有任何意义。

抛出错误的行在我们的 DAL 中,它在其中查询一个表以获取与指定父键相关的主键列表:

Select 
    ItemKey
From Items
Where ItemParentKey = @Key

Create Table Items
(
    ItemKey int identity(1,1) not null
    ,ItemParentKey int
    ,constraint PK_Items primary key clustered (ItemKey)
)

在 .net 端,我们使用 SQL 数据适配器的填充方法来调用包含上述选择语句的存储过程,并将结果加载到数据表中。当我们尝试遍历数据表的行并对键执行某些操作时会发生错误,所有键都是空的,这会导致无效的强制转换异常。数据表在 xsd 文件中定义,其中包含一个名为 Key 的整数列。

Adapter.Fill(data);
foreach(KeyListRow Row in data.KeyList)
{
    Item.Children.Add(Row.Key);  //Invalid cast exception
}

应该注意,实际上是设计器生成的代码在尝试转换为强类型列时抛出异常,这是我们能够捕获它的地方。

对此进行尝试并添加代码以记录查询参数的详细信息和结果表明查询正在为参数值返回正确的行数,但它们都返回 null...(这不应该可以通过上面的查询和表定义)

再加上其他几点,这是间歇性的,它将工作数天或数周而没有问题,然后在一周内每小时崩溃一次。在应用程序关闭时手动执行存储过程并检查导致错误的记录的数据会显示预期值,而不是应用程序在日志中报告的结果。重新启动站点的应用程序池将清除问题并使我们恢复正常,直到它再次开始发生。流量水平与应用程序出现故障的频率之间似乎存在轻微的相关性,但到目前为止我们还无法具体隔离。

关于可能的原因或进一步调查途径的任何建议?


编辑 2015-03-16

异常详情:

ExceptionType - ExceptionMessage(深入了解内部异常)

  1. System.Web.HttpUnhandledException - 引发了“System.Web.HttpUnhandledException”类型的异常。
  2. System.Data.StrongTypingException - 表“KeyList”中“Key”列的值为 DBNull。
  3. System.InvalidCastException - 指定的强制转换无效。

正在返回的数据:

data.KeyList.Count: 7;
data.KeyList[0].Key: NULL;
data.KeyList[1].Key: NULL;
data.KeyList[2].Key: NULL;
data.KeyList[3].Key: NULL;
data.KeyList[4].Key: NULL;
data.KeyList[5].Key: NULL;
data.KeyList[6].Key: NULL;

设计师生成的代码:

public partial class dsXXXX : global::System.Data.DataSet
{

    private KeyListDataTable tableKeyList;

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
    [global::System.ComponentModel.Browsable(false)]
    [global::System.ComponentModel.DesignerSerializationVisibility(global::System.ComponentModel.DesignerSerializationVisibility.Content)]
    public KeyListDataTable KeyList {
        get {
            return this.tableKeyList;
        }
    }

    /// <summary>
    ///Represents the strongly named DataTable class.
    ///</summary>
    [global::System.Serializable()]
    [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedTableSchema")]
    public partial class KeyListDataTable : global::System.Data.TypedTableBase<KeyListRow> {

        private global::System.Data.DataColumn columnKey;

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public KeyListDataTable() {
            this.TableName = "KeyList";
            this.BeginInit();
            this.InitClass();
            this.EndInit();
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        internal KeyListDataTable(global::System.Data.DataTable table) {
            this.TableName = table.TableName;
            if ((table.CaseSensitive != table.DataSet.CaseSensitive)) {
                this.CaseSensitive = table.CaseSensitive;
            }
            if ((table.Locale.ToString() != table.DataSet.Locale.ToString())) {
                this.Locale = table.Locale;
            }
            if ((table.Namespace != table.DataSet.Namespace)) {
                this.Namespace = table.Namespace;
            }
            this.Prefix = table.Prefix;
            this.MinimumCapacity = table.MinimumCapacity;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        protected KeyListDataTable(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) : 
                base(info, context) {
            this.InitVars();
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public global::System.Data.DataColumn KeyColumn {
            get {
                return this.columnKey;
            }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        [global::System.ComponentModel.Browsable(false)]
        public int Count {
            get {
                return this.Rows.Count;
            }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public KeyListRow this[int index] {
            get {
                return ((KeyListRow)(this.Rows[index]));
            }
        }

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public event KeyListRowChangeEventHandler KeyListRowChanging;

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public event KeyListRowChangeEventHandler KeyListRowChanged;

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public event KeyListRowChangeEventHandler KeyListRowDeleting;

        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public event KeyListRowChangeEventHandler KeyListRowDeleted;

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public void AddKeyListRow(KeyListRow row) {
            this.Rows.Add(row);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public KeyListRow AddKeyListRow(int Key) {
            KeyListRow rowKeyListRow = ((KeyListRow)(this.NewRow()));
            object[] columnValuesArray = new object[] {
                    Key};
            rowKeyListRow.ItemArray = columnValuesArray;
            this.Rows.Add(rowKeyListRow);
            return rowKeyListRow;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public override global::System.Data.DataTable Clone() {
            KeyListDataTable cln = ((KeyListDataTable)(base.Clone()));
            cln.InitVars();
            return cln;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        protected override global::System.Data.DataTable CreateInstance() {
            return new KeyListDataTable();
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        internal void InitVars() {
            this.columnKey = base.Columns["Key"];
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        private void InitClass() {
            this.columnKey = new global::System.Data.DataColumn("Key", typeof(int), null, global::System.Data.MappingType.Element);
            base.Columns.Add(this.columnKey);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public KeyListRow NewKeyListRow() {
            return ((KeyListRow)(this.NewRow()));
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        protected override global::System.Data.DataRow NewRowFromBuilder(global::System.Data.DataRowBuilder builder) {
            return new KeyListRow(builder);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        protected override global::System.Type GetRowType() {
            return typeof(KeyListRow);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        protected override void OnRowChanged(global::System.Data.DataRowChangeEventArgs e) {
            base.OnRowChanged(e);
            if ((this.KeyListRowChanged != null)) {
                this.KeyListRowChanged(this, new KeyListRowChangeEvent(((KeyListRow)(e.Row)), e.Action));
            }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        protected override void OnRowChanging(global::System.Data.DataRowChangeEventArgs e) {
            base.OnRowChanging(e);
            if ((this.KeyListRowChanging != null)) {
                this.KeyListRowChanging(this, new KeyListRowChangeEvent(((KeyListRow)(e.Row)), e.Action));
            }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        protected override void OnRowDeleted(global::System.Data.DataRowChangeEventArgs e) {
            base.OnRowDeleted(e);
            if ((this.KeyListRowDeleted != null)) {
                this.KeyListRowDeleted(this, new KeyListRowChangeEvent(((KeyListRow)(e.Row)), e.Action));
            }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        protected override void OnRowDeleting(global::System.Data.DataRowChangeEventArgs e) {
            base.OnRowDeleting(e);
            if ((this.KeyListRowDeleting != null)) {
                this.KeyListRowDeleting(this, new KeyListRowChangeEvent(((KeyListRow)(e.Row)), e.Action));
            }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public void RemoveKeyListRow(KeyListRow row) {
            this.Rows.Remove(row);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedTableSchema(global::System.Xml.Schema.XmlSchemaSet xs) {
            global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType();
            global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence();
            dsXXXX ds = new dsXXXX();
            global::System.Xml.Schema.XmlSchemaAny any1 = new global::System.Xml.Schema.XmlSchemaAny();
            any1.Namespace = "http://www.w3.org/2001/XMLSchema";
            any1.MinOccurs = new decimal(0);
            any1.MaxOccurs = decimal.MaxValue;
            any1.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax;
            sequence.Items.Add(any1);
            global::System.Xml.Schema.XmlSchemaAny any2 = new global::System.Xml.Schema.XmlSchemaAny();
            any2.Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1";
            any2.MinOccurs = new decimal(1);
            any2.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax;
            sequence.Items.Add(any2);
            global::System.Xml.Schema.XmlSchemaAttribute attribute1 = new global::System.Xml.Schema.XmlSchemaAttribute();
            attribute1.Name = "namespace";
            attribute1.FixedValue = ds.Namespace;
            type.Attributes.Add(attribute1);
            global::System.Xml.Schema.XmlSchemaAttribute attribute2 = new global::System.Xml.Schema.XmlSchemaAttribute();
            attribute2.Name = "tableTypeName";
            attribute2.FixedValue = "KeyListDataTable";
            type.Attributes.Add(attribute2);
            type.Particle = sequence;
            global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable();
            if (xs.Contains(dsSchema.TargetNamespace)) {
                global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream();
                global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream();
                try {
                    global::System.Xml.Schema.XmlSchema schema = null;
                    dsSchema.Write(s1);
                    for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) {
                        schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current));
                        s2.SetLength(0);
                        schema.Write(s2);
                        if ((s1.Length == s2.Length)) {
                            s1.Position = 0;
                            s2.Position = 0;
                            for (; ((s1.Position != s1.Length) 
                                        && (s1.ReadByte() == s2.ReadByte())); ) {
                                ;
                            }
                            if ((s1.Position == s1.Length)) {
                                return type;
                            }
                        }
                    }
                }
                finally {
                    if ((s1 != null)) {
                        s1.Close();
                    }
                    if ((s2 != null)) {
                        s2.Close();
                    }
                }
            }
            xs.Add(dsSchema);
            return type;
        }
    }

    /// <summary>
    ///Represents strongly named DataRow class.
    ///</summary>
    public partial class KeyListRow : global::System.Data.DataRow {

        private KeyListDataTable tableKeyList;

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        internal KeyListRow(global::System.Data.DataRowBuilder rb) : 
                base(rb) {
            this.tableKeyList = ((KeyListDataTable)(this.Table));
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public int Key {
            get {
                try {
                    return ((int)(this[this.tableKeyList.KeyColumn]));
                }
                catch (global::System.InvalidCastException e) {
/*****Exception is thrown here*****/
                    throw new global::System.Data.StrongTypingException("The value for column \'Key\' in table \'KeyList\' is DBNull.", e);
                }
            }
            set {
                this[this.tableKeyList.KeyColumn] = value;
            }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public bool IsKeyNull() {
            return this.IsNull(this.tableKeyList.KeyColumn);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")]
        public void SetKeyNull() {
            this[this.tableKeyList.KeyColumn] = global::System.Convert.DBNull;
        }
    }

}

【问题讨论】:

  • 请发布完整的异常,包括内部异常。捕获异常然后发布ex.ToString()。另外,KeyTableRow 是什么?实际上,您在 C# 代码中使用的所有类型的定义是什么?最后,试试var key = Row.Key; /* newline */ Item.Children.Add(key);,看看它在哪一行中断。
  • @John 我们已经完成了所有这些。如前所述,表行是在 dataset(xsd) 文件中定义的数据表。它是一个单列表,列定义为 int。当设计器尝试将原始 DB 结果转换为强类型 int 时,会在设计器生成的代码中引发异常。我继续添加了完整异常堆栈的异常类型和消息信息,以及我们的调试代码记录的值。
  • 您是否希望返回 7 行?如果是这样,这是一个很大的线索。我怀疑表中的列名为ItemKey,但DataTable 中的列名为Key。我怀疑您已检索到正确的 7 行,但您要查找的 ItemKey 在您的表中没有位置。
  • @John 是的,我们期待 7 行,但数据适配器按位置填充映射,而不是名称。另请注意,这将毫无问题地执行数千次,然后在某个看似随机的时间开始抛出错误。重置应用程序池将修复它,并且该站点将在一些新的随机持续时间内正常运行。就我个人而言,我怀疑某种形式的资源匮乏正在起作用,但我们目前还无法隔离任何东西。
  • 如果存在资源匮乏问题,如果列中有 7 行 null 数据,我会感到惊讶。不过,请使用 ReSharper 尝试查找未将 IDisposable 实例放入 using 块中的位置。

标签: asp.net sql-server sqldataadapter


【解决方案1】:

我们从未查出此问题的确切原因,但我们的服务器团队将一些其他应用程序移至另一台服务器,而这台服务器又开始运行了。所以所有指标都表明我们正在处理某种形式的资源匮乏或类似的冲突。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-20
    • 1970-01-01
    相关资源
    最近更新 更多