jp2*_*ode 44 c# datatable sqlcommand sqldataadapter
我有一小段代码,它最初反复创建了一个SqlDataAdapter对象.
尝试简化我的调用,我用SqlCommand替换了SqlDataAdapter,并将SqlConnection移到了循环之外.
现在,每当我尝试编辑返回到我的DataTable的数据行时,我都会抛出之前未抛出的ReadOnlyException.
注意:我有一个自定义函数,可根据其ID检索员工的全名.为简单起见,我在下面的示例代码中使用了"John Doe"来证明我的观点.
ExampleQueryOld与SqlDataAdapter一起使用 ; 每当我尝试写入DataRow的元素时,ExampleQueryNew都会因ReadOnlyException 而失败:
这有效,没有问题:
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;
}
Run Code Online (Sandbox Code Playgroud)
此示例抛出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;
}
Run Code Online (Sandbox Code Playgroud)
为什么我可以在一种情况下写入DataRow元素,而不是在另一种情况下写入?
是因为SqlConnection仍处于打开状态还是SqlDataAdapter在场景后面做了什么?
Fun*_*eng 87
using DataAdapter.Fill不加载数据库模式,其中包括列是否为主键,以及列是否为只读.要加载数据库架构,请使用DataAdapter.FillSchema,但那不是您的问题.
通过DataReader填写表格加载模式.因此,该index列是只读的(可能是因为它是主键)并且该信息被加载到DataTable.从而阻止您修改表中的数据.
我认为@ k3b做对了; 通过设置ReadOnly = false,您应该能够写入数据表.
foreach (System.Data.DataColumn col in tab.Columns) col.ReadOnly = false;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
51942 次 |
| 最近记录: |