如果你只是想要一个数据表,然后下面的方法很短,降低了复杂性:
public DataTable GetDataForSql(string sql, string connectionString)
{
using(SqlConnection connection = new SqlConnection(connectionString))
{
using(SqlCommand command = new SqlCommand())
{
command.CommandType = CommandType.Text;
command.Connection = connection;
command.CommandText = sql;
connection.Open();
using(SqlDataReader reader = command.ExecuteReader())
{
DataTable data = new DataTable();
data.Load(reader);
return data;
}
}
}
}
用法:
try{
DataTable results = GetDataForSql("SELECT * FROM Table;", ApplicationSettings["ConnectionString"]);
}
catch(Exception e)
{
//Logging
//Alert to user that command failed.
}
是不是真的有必要在这里使用DataAdapter - 这是不是真的为了你想要的。如果使用更新,删除或插入命令,为什么还要去捕捉异常等等?它不适合你想要做的事情。
这是重要到注的SelectCommand属性没有做什么特别的东西 - 在执行SelectCommand中时,它仍然会运行任何命令传递给它 - 它只是expects一个结果被返回,如果没有结果返回,那么它返回一个空的数据集。
这意味着(你应该这样做),你应该显式授予SELECT权限到你希望人们能够查询的表。
编辑
为了回答您的其他问题,SqlDataReader的是ReadOnly
,因为他们通过只读流水式的游标工作。这实际上意味着什么:
while(reader.Read()) //Reads a row at a time moving forward through the resultset (`cursor`)
{
//Allowed
string name = reader.GetString(reader.GetOrdinal("name"));
//Not Allowed - the read only bit means you can't update the results as you move through them
reader.GetString(reader.GetOrdina("name")) = name;
}
它是只读的,因为它不允许您在遍历它们时更新记录。没有理由说为什么他们执行得到结果集的sql不能更新数据。
duplicate - http://stackoverflow.com/questions/4900630/dataadapter-fill-command-prohibit-write-operation – Tobsey
另一种选择可能是使用DataTable.Load方法带一个SqlDataReader,所以你没有除了DataTable.Load(command.ExecuteReader())以外的任何其他操作。 – dash
另外请注意,你不应该仅仅依靠这一点 - 确保你恰当地允许表的SELECT权限('GRANT SELECT ON [Table] TO [User]')。有人可能按照SELECT * FROM User; DROP TABLE User;的语句输入内容:这在技术上是一个返回结果集的sql语句:SelectCommand属性就是将抽象数据加载到适配器中 - 它不会做任何事情来防止错误的sql被运行。 – dash