我有一小段代码,最初多次创建了一个 SqlDataAdapter 对象。
为了使调用更加简洁,我将 SqlDataAdapter 替换为 SqlCommand,并将 SqlConnection 移到循环外部。
现在,每当我尝试编辑返回到我的 DataTable 的数据行时,会抛出一个以前没有出现过的 ReadOnlyException 异常。
注意:我有一个自定义函数,根据员工的ID获取他们的全名。这里为了简单起见,我在下面的示例代码中使用了"John Doe"来演示我的观点。
ExampleQueryOld 使用 SqlDataAdapter;每当我尝试写入 DataRow 的元素时,ExampleQueryNew 就会失败,并抛出 ReadOnlyException:
- ExampleQueryOld
这个可行且没有问题:
public static DataTable ExampleQueryOld(string targetItem, string[] sqlQueryStrings) {
DataTable bigTable = new DataTable();
for (int i = 0; i < sqlQueryStrings.Length; i++) {
string sqlText = sqlQueryStrings[i];
DataTable data = new DataTable(targetItem);
using (SqlDataAdapter da = new SqlDataAdapter(sqlText, Global.Data.Connection)) {
try {
da.Fill(data);
} catch (Exception err) {
Global.LogError(_CODEFILE, err);
}
}
int rowCount = data.Rows.Count;
if (0 < rowCount) {
int index = data.Columns.IndexOf(GSTR.Employee);
for (int j = 0; j < rowCount; j++) {
DataRow row = data.Rows[j];
row[index] = "John Doe"; // This Version Works
}
bigTable.Merge(data);
}
}
return bigTable;
}
- ExampleQueryNew(示例查询新)
这个示例会抛出 ReadOnlyException(只读异常):
public static DataTable ExampleQueryNew(string targetItem, string[] sqlQueryStrings) {
DataTable bigTable = new DataTable();
using (SqlConnection conn = Global.Data.Connection) {
for (int i = 0; i < sqlQueryStrings.Length; i++) {
string sqlText = sqlQueryStrings[i];
using (SqlCommand cmd = new SqlCommand(sqlText, conn)) {
DataTable data = new DataTable(targetItem);
try {
if (cmd.Connection.State == ConnectionState.Closed) {
cmd.Connection.Open();
}
using (SqlDataReader reader = cmd.ExecuteReader()) {
data.Load(reader);
}
} catch (Exception err) {
Global.LogError(_CODEFILE, err);
} finally {
if ((cmd.Connection.State & ConnectionState.Open) != 0) {
cmd.Connection.Close();
}
}
int rowCount = data.Rows.Count;
if (0 < rowCount) {
int index = data.Columns.IndexOf(GSTR.Employee);
for (int j = 0; j < rowCount; j++) {
DataRow row = data.Rows[j];
try {
// ReadOnlyException thrown below: "Column 'index' is read only."
row[index] = "John Doe";
} catch (ReadOnlyException roErr) {
Console.WriteLine(roErr.Message);
}
}
bigTable.Merge(data);
}
}
}
}
return bigTable;
}
为什么我在一个情况下可以写入DataRow元素,但在另一个情况下却不能呢?
是因为SqlConnection仍然处于打开状态,还是SqlDataAdapter在幕后做了一些事情?
DataTable.Load(IReader)
方法将列设置为只读。你可以将所有列的ReadOnly
属性设置为 false 吗? - Mike ParkDataTable
、DataRow
和DataRow item
没有ReadOnly
属性,我尝试使用DataTable.Load(IReader, LoadOption.Upsert)
、DataTable.Load(IReader, LoadOption.Upsert)
(默认值)和DataTable.Load(IReader, LoadOption.OverwriteChanges)
修改了DataTable.Load(IReader)
命令,但结果都是一样的:ReadOnlyException
。 - user153923