由于在使用中发现这个问题所以到MSDN查找到了以下可能会触发问题的代码,但未找到解决办法
以下是转发微软的资料:
FIX: 与使用 System.Data 对象组件相关联数据可能损坏, 基于 Microsoft NET Framework 2.0 应用程序中
注意:这篇文章是由无人工介入的自动的机器翻译系统翻译完成。这些文章是微软为不懂英语的用户提供的, 以使他们能够理解这些文章的内容。微软不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的使用所引起的任何直接的, 或间接的可能的问题负责。
症状
当您尝试应用程序, 基于 Microsoft NET Framework 2.0, 中使用组件数据与组件时可能损坏。 该组件使用 System.Data.DataSet 对象时出现此问题。 发生此问题时, 可能会遇到一个或多个下列问题:
•
记录管理器在调用 AcceptChanges 方法 DataView 类中, 可能损坏。
•
可能无法正确更新表达式列中计算值。
•
通过使用多个语句, 调用 DataTable.Select 方法时可能会返回正确结果。
•
可能的 DataTable 对象内部索引损坏。 此外, 收到 ' 13 ' 错误信息。
•
合并操作时, 如果目标行处于编辑状态可能损坏记录管理器。
•
可能的 DataTable 对象内部索引损坏。 此外, 收到 5 ' ' 错误信息。
解决方案
支持修补程序现已推出来自 Microsoft。 但是, 它旨在解决只问题本文中描述。 它仅适用于系统是经历此特定问题。 此修复程序可能需要接受其他测试。 因此, 如果您受此问题, 的影响不严重我们建议您等待下 Microsoft NET Framework 2.0 服务包包含此修复程序。
要立即, 解决问题请与 Microsoft 客户支持服务以获取此修复程序。 有关 Microsoft 客户支持服务电话号码和支持费用, 信息的完整列表请访问 Microsoft Web 站点:
http://support.microsoft.com/contactus/?ws=support (http://support.microsoft.com/contactus/?ws=support)
注意 在特殊情况下, 如果 Microsoft 支持专家确定该特定更新将解决问题可能是免, 是正常收取支持电话费用。 通常支持成本将应用于其他支持问题和问题做不符合特定更新问题。
先决条件
有用于安装此修复程序没有先决条件。重新启动要求
您没有要应用此修复程序后重新启动计算机修补程序替换信息
此修复程序不替代任何其他修复程序。文件信息
文件属性 (或更高文件属性) 的此修复程序英文版具有下表中列出。 中协调通用时间 (UTC) 列出日期和时间对这些文件。 当您查看文件信息, 将转换为本地时间。 要查找 UTC 与本地时间, 区别控制面板中 DateandTime 项目中使用 时区 选项卡。对记录管理器调用 AcceptChanges 方法 DataView 类中, 时可能会损坏问题 1:
从事件处理程序写操作期间可能发生记录经理损坏。 这时, System.NullreferenceException 异常可能引发。 按正确顺序此外, 当应用程序执行写入操作 ListChanged 事件, 中可能出现索引更新。例如, 考虑以下情形:
1.
您在应用程序使用以下代码:
using System;
using System.ComponentModel;
using System.Data;
class Test
{
private static DataRow _dr = null;
private static bool _accept = false;
public static void Main()
{
try
{
DataSet ds = new DataSet();
DataTable dt = ds.Tables.Add("Customers");
DataColumn c = dt.Columns.Add("Id", typeof(int));
dt.PrimaryKey = new DataColumn[] { c };
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Age", typeof(int));
dt.Rows.Add(new object[] { 1, "A", 10 });
dt.Rows.Add(new object[] { 2, "B", 20 });
dt.Rows.Add(new object[] { 3, "G", 30 });
dt.Rows.Add(new object[] { 4, "H", 40 });
dt.Rows.Add(new object[] { 5, "I", 50 });
ds.AcceptChanges();
DataView dv = new DataView(dt);
dv.Sort = "Name ASC";
dv.ListChanged += new ListChangedEventHandler(OnListChanged);
_dr = dt.Rows[4];
_accept = true;
_dr["Name"] = "C";
_accept = false;
_dr["Name"] = "D";
_dr["Age"] = 55;
Console.WriteLine(dv[2][1]);
}
catch (Exception exc)
{
Console.WriteLine(exc);
}
}
public static void OnListChanged(object sender, ListChangedEventArgs args)
{
if (_dr != null && _accept)
{
_dr.AcceptChanges();
}
}
}
2.
运行该应用程序。
在此方案, 收到错误信息类似以下错误信息:
未设置为对象的实例 System.NullReferenceException: 对象引用。 c:\Work\bugs\newbug1\Test.cs:line 42 中 Test.Main() 上 System.Data.DataRowView.get_Item (Int 32 ndx) 上 System.Data.DataView.IsOriginalVersion (Int 32 index) 上
要变通解决此问题, 不在 ListChanged 事件执行写入操作。 最好使用 RowChanged 事件代替 ListChanged 事件。
一个表达式列中: 计算值可能无法正确更新问题 2:
当您尝试计算, DataSet 对象中的表达式列的值, 表达式列是关系, 一部分可能无法正确更新计算值的表达式列。 例如, 考虑以下情形:1.
您在应用程序使用以下代码:
using System.ComponentModel;
using System.Data;
class Test
{
public static void Main()
{
try
{
DataSet ds = new DataSet();
DataTable dt1 = ds.Tables.Add( " T1 " );
dt1.Columns.Add( " CustId " , typeof ( int ));
dt1.Columns.Add( " CustName " , typeof ( string ));
DataTable dt2 = ds.Tables.Add( " T2 " );
dt2.Columns.Add( " EmpId " , typeof ( int ));
DataColumn dcEmpName = dt2.Columns.Add( " EmpName " , typeof ( string ));
DataColumn dcMgrName = dt2.Columns.Add( " MgrName " , typeof ( string ));
DataColumn dcReports = dt2.Columns.Add( " NumberOfReports " , typeof ( int ));
DataRelation rel1 = ds.Relations.Add( " T1T2 " , dt1.Columns[ " CustId " ], dt2.Columns[ " EmpId " ], false );
DataRelation rel2 = ds.Relations.Add( " T2T2 " , dt2.Columns[ " EmpName " ], dt2.Columns[ " MgrName " ], false );
dcEmpName.Expression = " Parent(T1T2).CustName " ;
dcMgrName.Expression = " Parent(T1T2).CustName " ;
// Each person is a manager to himself.
dcReports.Expression = " Count(Child(T2T2).EmpName) " ;
AddRow(dt1, 1 , " N1 " );
AddRow(dt1, 2 , " N2 " );
AddRow(dt1, 3 , " N3 " );
AddRow(dt2, 1 );
AddRow(dt2, 2 );
AddRow(dt2, 3 );
Console.WriteLine(ds.GetXml());
dt1.Rows[ 0 ][ " CustName " ] = " N4 " ;
Console.WriteLine(ds.GetXml());
}
catch (Exception exc)
{
Console.WriteLine(exc);
}
}
public static void AddRow(DataTable dt, params object [] objArr)
{
Console.WriteLine( " Adding row to table {0} " , dt.TableName);
dt.Rows.Add(objArr);
}
}
2.
运行该应用程序。
在此方案, 您收到以下输出:
< T1 >
< CustId > 1 </ CustId >
< CustName > N4 </ CustName >
</ T1 >
< T1 >
< CustId > 2 </ CustId >
< CustName > N2 </ CustName >
</ T1 >
< T1 >
< CustId > 3 </ CustId >
< CustName > N3 </ CustName >
</ T1 >
< T2 >
< EmpId > 1 </ EmpId >
< EmpName > N4 </ EmpName >
< MgrName > N4 </ MgrName >
< NumberOfReports > 0 </ NumberOfReports >
</ T2 >
< T2 >
< EmpId > 2 </ EmpId >
< EmpName > N2 </ EmpName >
< MgrName > N2 </ MgrName >
< NumberOfReports > 1 </ NumberOfReports >
</ T2 >
< T2 >
< EmpId > 3 </ EmpId >
< EmpName > N3 </ EmpName >
< MgrName > N3 </ MgrName >
< NumberOfReports > 1 </ NumberOfReports >
</ T2 >
</ NewDataSet >
问题 3: 通过使用多个语句, 调用 DataTable.Select 方法时可能会返回正确结果
当您使用 选择 方法同时具有 AND 子句的 DataTable 对象来检索数据对于多语句, 选择 方法可能返回正确结果。 例如, 以下代码返回正确结果:
string filter = "(NOT ColTwo = 1) AND (ColOne = 2)";
DataTable.Select(filter);
但是, 下列代码返回正确结果:
string filter = "NOT ColTwo = 1 AND ColOne = 2";
DataTable.Select(filter);
此外, 请考虑以下情形:
1.
您在应用程序使用以下代码:
public static void Main()
{
DataTable table = new DataTable();
table.Columns.Add("ColID", typeof(int));
table.Columns.Add("ColOne", typeof(int));
table.Columns.Add("ColTwo", typeof(int));
table.Rows.Add(new object[] { 1, 1, 1 });
table.Rows.Add(new object[] { 2, 1, 2 });
table.Rows.Add(new object[] { 3, 2, 1 });
table.Rows.Add(new object[] { 4, 2, 2 });
string[] queries = new string[] {
"(NOT ColTwo = 1) AND (ColOne = 2)",
"(ColOne = 2) AND (NOT ColTwo = 1)",
"NOT ColTwo = 1 AND ColOne = 2",
"ColOne = 2 AND NOT ColTwo = 1",
"NOT ColTwo = 1 AND (ColOne = 2)",
"(ColOne = 2) AND NOT ColTwo = 1",
"(NOT ColTwo = 1) AND ColOne = 2",
"ColOne = 2 AND (NOT ColTwo = 1)",
};
Console.WriteLine("Select");
foreach(string query in queries) {
DataRow[] rows = table.Select(query);
Console.WriteLine("query=\"{0}\" count={1}", query, rows.Length);
foreach(DataRow row in rows) {
Console.WriteLine("\t{0}, {1}, {2}", row[0], row[1], row[2]);
}
}
}
2.
运行该应用程序。
在此方案, 您收到以下输出:
query="(NOT ColTwo = 1) AND (ColOne = 2)" count=2
3, 2, 1
4, 2, 2
query="(ColOne = 2) AND (NOT ColTwo = 1)" count=1
4, 2, 2
query="NOT ColTwo = 1 AND ColOne = 2" count=1
4, 2, 2
query="ColOne = 2 AND NOT ColTwo = 1" count=1
4, 2, 2
query="NOT ColTwo = 1 AND (ColOne = 2)" count=2
3, 2, 1
4, 2, 2
query="(ColOne = 2) AND NOT ColTwo = 1" count=1
4, 2, 2
query="(NOT ColTwo = 1) AND ColOne = 2" count=1
4, 2, 2
query="ColOne = 2 AND (NOT ColTwo = 1)" count=1
4, 2, 2
此输出, "(ColOne = 2) 中 " 右侧的 AND 子句上正确显示。
问题 4: 可能损坏的 DataTable: 内部索引, 并且您收到 ' 13 ' 错误信息
当尝试使用的由 DataTable 对象, 使用 DataSet 对象 AcceptChanges 方法并且您设置到 AcceptRule.Cascade , ForeignKey 规则所使用的 DataSet 对象内部索引值可能损坏。 如果下列条件为真会发生此问题:•
DataSet 对象包含一个或多个表具有到一对多关系。
•
调用 AcceptChanges 方法的 DataSet 对象。
•
DataSet 对象的 < A0 > AcceptRejectRule < / A0 > 值设置为层叠。 当此值设为层叠, 子表将更改以便它自动或者接受数据或者拒绝数据。
例如, 考虑以下情形:
1.
您在应用程序使用以下代码:
{
DataTable Table = new DataTable( " Employee " );
Table.Columns.Add( " Id " , typeof ( int ));
Table.Columns.Add( " ManagerId " , typeof ( int ));
Table.Columns.Add( " Name " , typeof ( string ));
Table.Columns[ " Name " ].AllowDBNull = false ;
Table.PrimaryKey = new DataColumn[] { Table.Columns[ " Id " ] };
DataSet Employees = new DataSet();
Employees.Tables.Add(Table);
DataRelation rel = Employees.Relations.Add(Table.Columns[ " ID " ], Table.Columns[ " ManagerId " ]);
rel.ChildKeyConstraint.AcceptRejectRule = AcceptRejectRule.Cascade;
DataRow ManagerA = Table.NewRow();
ManagerA[ " ID " ] = 2019 ;
ManagerA[ " Name " ] = " Manager A " ;
Table.Rows.Add(ManagerA);
DataRow ManagerB = Table.NewRow();
ManagerB[ " ID " ] = 392 ;
ManagerB[ " Name " ] = " Manager B " ;
Table.Rows.Add(ManagerB);
DataRow EmployeeB = Table.NewRow();
EmployeeB[ " ID " ] = 716 ;
EmployeeB[ " Name " ] = " Employee of B " ;
EmployeeB.SetParentRow(ManagerB);
Table.Rows.Add(EmployeeB);
EmployeeB = Table.NewRow();
EmployeeB[ " ID " ] = 637 ;
EmployeeB[ " Name " ] = " 2nd employee of B " ;
EmployeeB.SetParentRow(ManagerB);
Table.Rows.Add(EmployeeB);
Employees.AcceptChanges();
Table.Rows.Find( 392 ).Delete();
Employees.AcceptChanges();
}
2.
运行该应用程序。
此方案, 中收到以下错误信息:
DataTable 内部索引已损坏: ' 13 '。
问题 5: 合并操作发生, 时记录经理可能损坏如果目标行处于编辑状态
如果是 DataTable 对象中一个或多行编辑, 并再 DataTable.Merge 操作发生或者 DataSet.Merge 操作发生, 记录经理对 DataSet 对象是 DataTable 对象可能损坏。注意 正在编辑, DataTable 对象中某行时的行 DataRowVersion 值设置为建议。
例如, 考虑以下情形:
1.
您在应用程序使用以下代码:
using System.Data;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main( string [] args)
{
DataSet set = new DataSet();
DataTable table = set .Tables.Add( " table " );
table.Columns.Add( " C1 " , typeof ( int ));
table.Columns.Add( " C2 " , typeof ( char ));
table.PrimaryKey = new DataColumn[] { table.Columns[ 0 ] };
for ( int i = 0 ; i < 26 ; ++ i)
{
table.Rows.Add( new object [] { i, ( char )(( ushort ) ' a ' + i) });
}
table.AcceptChanges();
DataSet clone = set .Copy();
clone.Tables[ 0 ].Rows[ 0 ][ 1 ] = ' Z ' ;
// clone.AcceptChanges();
table.Rows[ 0 ][ 1 ] = ' 1 ' ;
table.Rows[ 0 ].BeginEdit();
table.Rows[ 0 ][ 1 ] = ' 2 ' ;
try
{
set .Merge(clone);
}
finally
{
foreach (DataRow row in table.Rows)
{
Console.WriteLine( " {0}={1} " , row[ 0 ], row[ 1 ]);
}
}
}
}
}
2.
运行该应用程序。
在此方案, 记录经理进行 DataSet 对象是 DataTable 对象损坏。
若要解决此问题, 处理请确认有目标 DataSet 对象中有 DataRowVersion 值设置为 < A0 > Proposed 使用 DataTable.Merge 方法或者 DataSet.Merge 方法之前没有行。
问题 6: 可能损坏的 DataTable 对象: 内部索引, 并且您收到 5 ' ' 错误信息
DataTable 对象中通过更改 DataTable 对象中的数据不更新的 DataTable 对象内部索引下列方案导致损坏:1.
DataColumn.Expression 值由表达式更改为任何表达式。 在此方案, DataColumn 对象中所有数据设置为 DBNull。
2.
调用 DataTable.Clear 方法, 时 DataTable 对象中所有数据被删除并更新索引。 但是, 不更新其他表, 引用 DataTable 对象。
例如, 考虑以下情形:
1.
您在应用程序使用以下代码:
using System;
using System.Data;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataSet set = new DataSet("s");
DataTable table1 = set.Tables.Add("a");
table1.Columns.Add("C1", typeof(int));
table1.Columns.Add("C2", typeof(int));
table1.DefaultView.Sort = "C2";
DataTable table2 = set.Tables.Add("b");
table2.Columns.Add("C1", typeof(int));
table2.Columns.Add("C2", typeof(int));
table2.DefaultView.Sort = "C2";
set.Relations.Add(new DataRelation("t1t2", table1.Columns[0], table2.Columns[0], false));
table1.Columns[1].Expression = "Sum(Child(t1t2).C2)";
AddData(table1, 1);
AddData(table2, 2);
table1.Columns[1].Expression = null;
AddData(table2, 2);
AddData(table1, 2);
}
private static void AddData(DataTable table, int y)
{
object[] x = new object[y];
Random rand = new Random(20070125);
for (int i = 0; i < 1000; ++i)
{
switch (rand.Next(3))
{
case 0:
case 1:
for (int k = 0; k < x.Length; ++k)
{
x[k] = rand.Next(500);
}
table.Rows.Add(x);
break;
case 2:
if (0 < table.Rows.Count)
{
table.Rows.RemoveAt(rand.Next(table.Rows.Count));
}
break;
}
}
}
}
}
2.
运行该应用程序。
此方案, 中收到以下错误信息:
DataTable 内部索引已损坏: ' 5 '。
有关详细信息, 请单击下列文章编号以查看 Microsoft 知识库中相应: