none
DataAdapter的Update问题 RRS feed

  • 问题

  • 我用两个窗体,Form1中有DGV,Form2是修改dt的表单(所有控件已绑定dt的列)。问题是在Form2里调用da的Update方法为什么只能更新dt,但不能更新数据库?但在Form1调用Update却可以更新数据库。这是为什么?如何在Form2点击Save按钮后让数据库和DGV及时更新?

    //在Form1里

    public static DataTable dt = new DataTable();
    public static SqlDataAdapter da = new SqlDataAdapter();
    public static DataSet ds = new DataSet();

    .......链接数据库和通过da填充DGV的数据.......

    private void btnSave_Click(object sender, EventArgs e)
    {

      da.Update(dt); //可以更新数据库和DGV

    }

    //在Form2里

    private void btnSave_Click(object sender, EventArgs e)
    {

       Form1.da.Update(Form1.dt); //可以更新dt,但不能更新数据库。关闭Form2,DGV聚焦后可以更新DGV。

    }

    2012年6月22日 9:22

全部回复

  • 你好:)

    就我而言,你必须在dataGridView中对数据库数据进行一些变更,然后打开Form2点击后方可更新数据进入数据库。否则你不对数据在GridView中进行任何更新,则直接打开Form2点击按钮之后是无法更新的(因为此时dt中数据是最新的数据,.NET判定不需要调用Update语句写入真实的数据库中)。


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月23日 5:52
    版主
  • 您好!谢谢了。我对您的说明的理解大概是这样:在Form2里变更的数据并不影响dt,dt仍然没变,因此.NET才判断dt的数据是最新的,所以不会执行UpDate。如果是这样的话,应该怎么办才能更新dt?
    2012年6月23日 7:30
  • 1)Form1的DataGridView绑定dt。

    2)在datagridView对某些列的数据进行变更。

    3)打开Form2,执行更新。


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月23日 8:25
    版主
  • 可能我说得不清楚,我的意思是DGV在Form1,从Form1打开Form2修改数据。Form2是特别用来增删改数据的表单,我的目的是增删改后直接在Form2点击Save按钮就可更新数据库。

    现在问题是点击Form2的Save按钮不能存储数据库,因此我在Form1也添加一个Save按钮作为调试,在Form2进行增删改后,关闭Form2,点击Form1的Save按钮就可以把在Form2变更的数据存于数据库。

    2012年6月23日 9:01
  • >>可能我说得不清楚,我的意思是DGV在Form1,从Form1打开Form2修改数据。Form2是特别用来增删改数据的表单,我的目的是增删改后直接在Form2点击Save按钮就可更新数据库

    那么你设法把dt绑定到Form2的TextBox上,比如:

    TextBox1.DataBindings.Add("Text",Form1.dt,"ColumnName");

    这样你先从dataGridView中选中一条dataGridView(把dataGridView的SelectMode改为FullRowSelect),然后打开Form2,在TextBox1中修改数据,最后点击Form2上的更新,最后退回到Form1,重新从数据库中选取全部数据填充数据到新的DataTable,然后绑定到dataGridView即可。


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月23日 9:05
    版主
  • 本来我在Form2的文本框就已绑定数据表的列,当关闭Form2后退到Form1,点击Form1的Save按钮就可把变更存于数据库。

    您的建议可能可行,但我的目的是在Form2调用Update就能解决,不必退到Form1时再调用Update或进行其他操作。非常谢谢您的建议。

    2012年6月23日 10:42
  • 那我建议你:

    1)在Form1中做这样一个静态公开方法(public):

    public static void UpdataDataGridView()
    {
    dt.Clear();
    adapter.Fill(dt);
    dataGridView1.DataSource = dt;
    }

    2)在Form2的Form_Closing事件中调用这个UpdataDataGridView方法即可。


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月23日 10:45
    版主
  • 您好!我的DataGridView1不是静态的,不能在静态方法里设定。这种从工具箱拉进来的控件如何声明为静态的?Modifier属性只能设置Public。
    2012年6月24日 3:21
  • 您好!我的DataGridView1不是静态的,不能在静态方法里设定。这种从工具箱拉进来的控件如何声明为静态的?Modifier属性只能设置Public。
    您好,没有让你把DataGridView设置为静态的,我只是让你在Form1定义一个静态public方法,可以直接在Form2中调用啊。请仔细看我上面的回复,谢谢!

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月24日 3:23
    版主
  • 您的回复很清楚,我照着做,但.NET提示有非静态字段的错误:

    错误 5 非静态的字段、方法或属性“CobaDGV.Form1.dgv”要求对象引用 C:\A-Bizdata\Programming\C# Sample\EasyMeal\CobaDGV\Form1.cs 352 10 EasyMeal

    注:dgv在我的代码里就是DataGridView1

    是不是静态方法里只能用非静态成员?

    2012年6月24日 3:48
  • 我的意思是dataGridView1.DataSource = dt;引发异常。
    2012年6月24日 3:55
  • Sorry……

    您这样做……

    1)在Form2中为Form1定义一个带参数的构造函数,把Form1实体直接引入到里边以便直接更新:

    public class Form2:Form
    {
      ………………
      private Form1 Form1{get;set;}
    
      public Form2(Form1 frm):this()
      {
       Form1 = frm;
      }
    
      //然后调用form1中静态方法之后直接使用:
      Form1.dataGridView = Form1.DataTable啥的……
    }
    
    //注意Form1中调用新的Form2实体时候——
    Form2 frm2 = new Form2(this);
    frm2.ShowDialog();

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月24日 4:06
    版主

  • 太麻烦您了!现在我把代码简化以方便讨论。以下是Form1和Form2的视图和代码,请您试试看(只须改用您的数据库而已)。我的目的是按下Form2的Save按钮后就能把变更存于数据库,同时DGV也立刻反映变更后的数据。以下代码执行时一切正常,只是不能把变更存储于数据库而已。

    注:“NamaSupplier”是印尼文,英语是“SupplierName”。

    //Form1类代码
    public partial class Form1 : Form
    {
       public static DataTable dtSupplier = new DataTable();
       public static SqlDataAdapter da = new SqlDataAdapter();
       public static DataSet ds = new DataSet();
       public static DataView dv = new DataView();

       public Form1()
       {
          InitializeComponent();
          string strConn = "Data Source=.\\xpw;Initial Catalog=EasyMeal;
             Integrated Security=True;";
          SqlConnection conn = new SqlConnection(strConn);
          conn.Open();
          string sqlSupplier = "SELECT * FROM supplier";

          da = new SqlDataAdapter(sqlSupplier, conn);
          SqlCommandBuilder cb = new SqlCommandBuilder(da);
          da.Fill(ds, "supplier");
          dtSupplier = ds.Tables["supplier"];
          dgv.DataSource = dtSupplier;
          dv = dtSupplier.DefaultView;
       }

       private void btnSave_Click(object sender, EventArgs e)
       {
          Form1.da.Update(Form1.dtSupplier);
       }

       private void btnShowForm2_Click(object sender, EventArgs e)
       {
          Form2 frm2 = new Form2(this);
          frm2.ShowDialog();
       }
    }

    //Form2类代码
    public partial class Form2 : Form
    {
       private Form1 f1 { get; set; }
       public BindingSource bsSupplier;

       public Form2(Form1 frm)
       {
          InitializeComponent();
          f1 = frm;
          bsSupplier = new BindingSource();
          bsSupplier.DataSource = Form1.ds.Tables["supplier"];
          textBox1.DataBindings.Add("Text", Form1.dtSupplier, "NamaSupplier");
       }

       public Form2()
       {
          InitializeComponent();
       }
    }

     

    2012年6月24日 6:12
  • public partial class Form2 : Form
    {
       private Form1 f1 { get; set; }
    
       public Form2(Form1 frm)
       {
          InitializeComponent();
          f1 = frm;
          textBox1.DataBindings.Add("Text", Form1.dtSupplier, "NamaSupplier");
       }
    
       public Form2()
       {
          InitializeComponent();
       }
    
       //假设有一个Update按钮
       private void Update_Click(object sender,EventArgs e)
       {
           f1.Update方法……
           f1.dataGrid1.Datasource = f1.dtSupplier;  //把dataGrid1设置成public或者internal即可。
           this.Close();
       }
    }

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月24日 6:24
    版主
  • 楼主:)

    如果你希望显示图像,请直接点击工具栏最后一个图标,直接上传一个静态图片即可。


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月24日 6:29
    版主
  • 我试了,还是无效。如您有时间,我建议您随便弄一个supplier数据表来检验。Form1的布局只是一个DGV和一个Show Form2按钮,Form2的布局是一个textBox1文本框和一个Save按钮,再添加一个您建议的Update按钮。

    非常感谢您的帮助!

    2012年6月24日 6:41
  • f1.Update方法……之前请加上:

    foreach(DataRow row in f1.dt……)

    {
    row.EndEdit();

    }


       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月24日 6:47
    版主
  • foreach引发异常:

    错误 1 “System.Data.DataTable”不包含“GetEnumerator”的公共定义,因此 foreach 语句不能作用于“System.Data.DataTable”类型的变量 C:\A-Bizdata\Programming\C# Sample\TryUpdate\TryUpdate\Form2.cs 34 10 TryUpdate

    2012年6月24日 7:38
  • foreach(DataRow row in f1.Dt…….Rows)

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月24日 7:52
    版主
  • 谢谢!

    2012年6月24日 8:48
  • 谢谢!

    不用谢!如果可以解决你问题,请麻烦标记答案哦!

       QQ我:讨论(Talk)
    下载MSDN桌面工具(Vista,Win7)
    我的博客园
    慈善点击,点击此处

    2012年6月24日 8:49
    版主
  • 问题确实还没有解决,也许必须改变方式。对不起!但再次谢谢!
    2012年6月24日 10:04