这是我在StackOverflow上的第一篇文章,所以请保持温和......
我对ADO.NET的对象范围有一些疑问。
当我连接到数据库时,我通常使用这样的代码:
OleDbConnection conn = new OleDbConnection("my_connection_string");
conn.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * from Employees", conn);
OleDbCommandBuilder cb = new OleDbCommandBuilder(adapter);
DataTable dt = new DataTable();
adapter.Fill(dt);
conn.Close();
conn.Dispose();
假设我将生成的DataTable绑定到网格控件并允许我的用户编辑网格内容。现在,当我的用户按下“保存”按钮时,我需要调用此代码:
adapter.Update(dt);
以下是我的问题:
1)我是否需要保留最初加载数据表时创建的适配器对象,还是可以在“保存”按钮单击事件中创建另一个适配器对象来执行更新?
2)如果我确实需要保留原始适配器对象,是否还需要保持连接对象可用并打开?
我理解ADO.NET的断开模型 - 我只是在更新数据库时对对象范围感到困惑。如果有人能给我一些关于这种情况的最佳实践的指示,我将非常感激!
提前致谢...
答案 0 :(得分:3)
1)您不需要相同的DataAdapter,但如果您创建一个新的DataAdapter,它必须使用与其基础相同的查询。
2)如果连接关闭,DataAdapter将打开其连接。在这种情况下,它将在完成后再次关闭连接。如果连接已经打开,即使完成连接也会使连接保持打开状态。
通常你会像你的例子一样工作。创建一个Conneciton和一个DataAdapter,填充DataTable并随后处理Connection和DataAdapter。
对您的代码发表两条评论:
尝试将代码更改为:
DataTable dt = new DataTable();
using (OleDbConnection conn = new OleDbConnection("my_connection_string"))
using (OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * from Employees", conn))
{
adapter.Fill(dt);
}
请注意,我在using子句之外定义了DataTable。这是确保在您离开使用时表格在范围内所必需的。另请注意,您不需要DataAdapter上的Dispose调用或Connection上的Close调用。当你离开使用时,两者都是隐式完成的。
喔。欢迎来到SO: - )
答案 1 :(得分:0)
回答你的问题:
理想情况下,您应该保留相同的DataAdapter,因为它已经执行了初始化。 DataAdapter提供了诸如SelectCommand,UpdateCommand,InsertCommand和DeleteCommand之类的属性,允许您设置不同的Command对象以在数据源上执行这些不同的功能。因此,您可以看到,DataAdapter的设计可以重用于多个命令(用于相同的数据库连接)。您使用CommandBuilder(但不推荐)通过分析SelectCommand创建其他命令,从而允许您使用相同的CommandBuilder执行更新,删除和插入。
最好允许DataAdapter隐式处理数据库连接。 @Rr Grimstad 已经详细阐述了这种隐含的行为,理解这一点很有用。理想情况下,应尽快关闭连接。
答案 2 :(得分:0)
还有两个额外的细节值得加入Rune Grimstad的优秀答案。
首先,CommandBuilder(如果需要)实现IDisposable,因此应该包含在它自己的'using'语句中。令人惊讶的是(至少对我来说),处理DataAdapter not 似乎处理关联的CommandBuilder。我没有做到这一点时遇到的问题是,即使我在DataAdapter上调用了Dispose,并且连接状态为“已关闭”,但在使用CommandBuilder更新该数据库后,我无法删除临时数据库。
其次,语句“ ...在这种情况下,您还需要手动设置DataAdapter上的InsertCommand,UpdateCommand或DeleteCommand ...... ”并不总是正确的。对于许多琐碎的情况,CommandBuilder将根据提供给DataAdapter的SELECT语句和来自数据库的元数据自动创建正确的INSERT,UPDATE和DELETE语句。在这种情况下,“Trivial”意味着只访问一个表,并且该表具有作为SELECT语句的一部分返回的主键。