none
请各位老大帮我查下primarykey引起的第一个记录丢失问题 RRS feed

  • 问题

  • //本程序演示 xml和Dataset互操作
    using System.Xml;
    using System.Data;
    using System.IO;
    using ADOX;//Microsft ADO Extension
    using System.Data.OleDb;
    class testdata
    {
        //这个例子演示如何将Dataset存入到XML文件中
        public static void Main(string[] args)
        {
            DataSet ods = new DataSet();
            DataTable odt = new DataTable("odtable");
            ods.Tables.Add(odt);

            odt.Columns.Add("booknum", typeof(string));
            odt.Columns.Add("bookname", typeof(string));

            odt.Rows.Add("BOOK1", "test in C#");
            odt.Rows.Add("BOOK2", "Inside in visual C#");
            odt.Rows.Add("BOOK3", "Herry Port");

            //接下来演示如何把dataset如何写入数据库中
            //先建立一个mdb数据库
            if (System.IO.File.Exists(@"d:\test3.mdb"))
                System.IO.File.Delete(@"d:\test3.mdb");
            Catalog oCat=new Catalog();
            string ostr = @"provider=Microsoft.Jet.Oledb.4.0; Data Source=d:\test3.mdb; jet oledb:engine type=5";
            oCat.Create(ostr);
            Table otb=new Table();
            otb.Name="table1";

             //设置parentCatalog非常重要,否则Properties[]加不进去。
            otb.Columns.Append("recordnum", DataTypeEnum.adInteger, 4);
            otb.Columns["recordnum"].ParentCatalog = oCat;
            otb.Columns["recordnum"].Properties["AutoIncrement"].Value = true;
            otb.Keys.Append("myprimarykey", ADOX.KeyTypeEnum.adKeyPrimary, "recordnum", null, null);


            otb.Columns.Append("booknum", DataTypeEnum.adVarWChar, 255);
           
           
            //允许bookname为空。纯演示目的用。默认情况下adox认为字段应非空。
            otb.Columns.Append("bookname", DataTypeEnum.adVarWChar, 255);
            otb.Columns["bookname"].Attributes = ColumnAttributesEnum.adColNullable;
            //设置默认值。 纯演示目的用。
            otb.Columns.Append("pressname", DataTypeEnum.adVarWChar, 255);
            otb.Columns["pressname"].ParentCatalog = oCat;
            otb.Columns["pressname"].Properties["default"].Value = "Tsinghua Express";


            oCat.Tables.Append(otb);

            //接下来演示如何写入数据库
            OleDbConnection ocn = new OleDbConnection(ostr);
            ocn.Open();
           
            //对部分字段进行赋值。要注意数据库字段名和dataset datatable列名完全一致。
            OleDbDataAdapter odb = new OleDbDataAdapter("select recordnum, booknum, bookname from table1",ocn);
            OleDbCommandBuilder odber = new OleDbCommandBuilder(odb);
            odb.InsertCommand = odber.GetInsertCommand();
            int i=odb.Update(ods,"odtable");
            System.Windows.Forms.MessageBox.Show(i.ToString());
            ocn.Close();
            ocn = new OleDbConnection(@"provider=microsoft.jet.oledb.4.0;data source=d:\test3.mdb");
            ocn.Open();
            OleDbCommand odcom= new OleDbCommand("select count(*) from table1",ocn);
            int j = (int)odcom.ExecuteScalar();
            System.Windows.Forms.MessageBox.Show(j.ToString());

        }
    }

    // 上述程序运行以后dataset数据表的第一个记录消失。若去掉recordnum的primarykey属性,则第一个记录能出现。请问,问什么?如何避免呢?


    Johnson Dai
    2010年12月19日 3:20

答案

  • 已经搞清楚了。原来使用ADOX创建完mdb数据库以后,要把catalog.activeconnection释放掉。当然,具体释放方法比较变态。是使用adodb的connection装箱,然后close掉。具体代码如下,供遇到该类问题的朋友参考。(我很奇怪的是为什么不直接做一个ADOX.close()之类的方法呢?)。。。微软的大侠们能不能把ADOX再鼓动几下?省的我老眼昏花地debug.

    using System.Xml;
    using System.Data;
    using System.IO;
    using ADOX;//Microsft ADO Extension
    using System.Data.OleDb;
    class testdata
    {
        //这个例子演示如何将Dataset存入到XML文件中
        public static void Main(string[] args)
        {
            //接下来演示如何把dataset如何写入数据库中
            //先建立一个mdb数据库
            if (System.IO.File.Exists(@"d:\test3.mdb"))
                System.IO.File.Delete(@"d:\test3.mdb");
            Catalog oCat = new Catalog();
            string ostr = @"provider=Microsoft.Jet.Oledb.4.0; Data Source=d:\test3.mdb; jet oledb:engine type=5";
            oCat.Create(ostr);
            Table otb = new Table();
            otb.Name = "table1";

            //设置parentCatalog非常重要,否则Properties[]加不进去。
            otb.Columns.Append("recordnum", ADOX.DataTypeEnum.adInteger, 4);
            otb.Columns["recordnum"].ParentCatalog = oCat;
            otb.Columns["recordnum"].Properties["AutoIncrement"].Value = true;
            otb.Keys.Append("myprimarykey", ADOX.KeyTypeEnum.adKeyPrimary, "recordnum", null, null);

           
            otb.Columns.Append("booknum", ADOX.DataTypeEnum.adVarWChar, 255);


            //允许bookname为空。纯演示目的用。默认情况下adox认为字段应非空。
            otb.Columns.Append("bookname", ADOX.DataTypeEnum.adVarWChar, 255);
            otb.Columns["bookname"].Attributes = ColumnAttributesEnum.adColNullable;
            //设置默认值。 纯演示目的用。
            otb.Columns.Append("pressname", ADOX.DataTypeEnum.adVarWChar, 255);
            otb.Columns["pressname"].ParentCatalog = oCat;
            otb.Columns["pressname"].Properties["default"].Value = "Tsinghua Express";

            oCat.Tables.Append(otb);
            if(oCat.ActiveConnection != null)//看这里。要写上这么一段。
            {
                ADODB.Connection os=(ADODB.Connection) oCat.ActiveConnection;
                os.Close();
            }

            //接下来演示如何写入数据库
            OleDbConnection ocn = new OleDbConnection(ostr);
            ocn = new OleDbConnection(ostr);
            ocn.Open();
            OleDbCommand oledbcommand = new OleDbCommand(@"insert into table1(booknum,bookname) values('book5','Programming visualBplus')", ocn);
            oledbcommand.ExecuteNonQuery();
            ocn.Close();

            ////对部分字段进行赋值。要注意数据库字段名和dataset datatable列名完全一致。
            //OleDbDataAdapter odb = new OleDbDataAdapter("select recordnum, booknum, bookname from table1", ocn);
            //OleDbCommandBuilder odber = new OleDbCommandBuilder(odb);
            //odb.InsertCommand = odber.GetInsertCommand();
            //int i = odb.Update(ods, "odtable");
            //System.Windows.Forms.MessageBox.Show(i.ToString());
            //ocn.Close();
            //ocn = new OleDbConnection(@"provider=microsoft.jet.oledb.4.0;data source=d:\test3.mdb");
            //ocn.Open();
            //OleDbCommand odcom = new OleDbCommand("select count(*) from table1", ocn);
            //int j = (int)odcom.ExecuteScalar();
            //System.Windows.Forms.MessageBox.Show(j.ToString());

        }
    }


    Johnson Dai
    • 已标记为答案 JohnsonDai 2010年12月19日 8:57
    2010年12月19日 8:56

全部回复

  • 刚才又试了一下,发现只要数据库中存在key(primarykey, foreign key, unique key)或者index,都会导致data adapter的update方法第一行记录丢失。不知道问题所在。


    Johnson Dai
    2010年12月19日 4:18
  • 去掉与dataset的相关部分,
    这样写也丢第一行。诧异。

    using System.Xml;
    using System.Data;
    using System.IO;
    using ADOX;//Microsft ADO Extension
    using System.Data.OleDb;
    class testdata
    {
        //这个例子演示如何将Dataset存入到XML文件中
        public static void Main(string[] args)
        {

           //接下来演示如何把dataset如何写入数据库中
            //先建立一个mdb数据库
            if (System.IO.File.Exists(@"d:\test3.mdb"))
                System.IO.File.Delete(@"d:\test3.mdb");
            Catalog oCat = new Catalog();
            string ostr = @"provider=Microsoft.Jet.Oledb.4.0; Data Source=d:\test3.mdb; jet oledb:engine type=5";
            oCat.Create(ostr);
            Table otb = new Table();
            otb.Name = "table1";

            //设置parentCatalog非常重要,否则Properties[]加不进去。
            otb.Columns.Append("recordnum", DataTypeEnum.adInteger, 4);
            otb.Columns["recordnum"].ParentCatalog = oCat;
            otb.Columns["recordnum"].Properties["AutoIncrement"].Value = true;
            otb.Keys.Append("myprimarykey", ADOX.KeyTypeEnum.adKeyPrimary, "recordnum", null, null);


            otb.Columns.Append("booknum", DataTypeEnum.adVarWChar, 255);


            //允许bookname为空。纯演示目的用。默认情况下adox认为字段应非空。
            otb.Columns.Append("bookname", DataTypeEnum.adVarWChar, 255);
            otb.Columns["bookname"].Attributes = ColumnAttributesEnum.adColNullable;
            //设置默认值。 纯演示目的用。
            otb.Columns.Append("pressname", DataTypeEnum.adVarWChar, 255);
            otb.Columns["pressname"].ParentCatalog = oCat;
            otb.Columns["pressname"].Properties["default"].Value = "Tsinghua Express";


            oCat.Tables.Append(otb);

            //接下来演示如何写入数据库
            OleDbConnection ocn = new OleDbConnection(ostr);
            ocn.Open();
            OleDbCommand oledbcommand = new OleDbCommand(@"insert into table1(booknum,bookname) values('book5','Programming visualBplus')",ocn);
            oledbcommand.ExecuteNonQuery();
            ocn.Close();

    }
    }


    Johnson Dai
    2010年12月19日 7:25
  • 已经搞清楚了。原来使用ADOX创建完mdb数据库以后,要把catalog.activeconnection释放掉。当然,具体释放方法比较变态。是使用adodb的connection装箱,然后close掉。具体代码如下,供遇到该类问题的朋友参考。(我很奇怪的是为什么不直接做一个ADOX.close()之类的方法呢?)。。。微软的大侠们能不能把ADOX再鼓动几下?省的我老眼昏花地debug.

    using System.Xml;
    using System.Data;
    using System.IO;
    using ADOX;//Microsft ADO Extension
    using System.Data.OleDb;
    class testdata
    {
        //这个例子演示如何将Dataset存入到XML文件中
        public static void Main(string[] args)
        {
            //接下来演示如何把dataset如何写入数据库中
            //先建立一个mdb数据库
            if (System.IO.File.Exists(@"d:\test3.mdb"))
                System.IO.File.Delete(@"d:\test3.mdb");
            Catalog oCat = new Catalog();
            string ostr = @"provider=Microsoft.Jet.Oledb.4.0; Data Source=d:\test3.mdb; jet oledb:engine type=5";
            oCat.Create(ostr);
            Table otb = new Table();
            otb.Name = "table1";

            //设置parentCatalog非常重要,否则Properties[]加不进去。
            otb.Columns.Append("recordnum", ADOX.DataTypeEnum.adInteger, 4);
            otb.Columns["recordnum"].ParentCatalog = oCat;
            otb.Columns["recordnum"].Properties["AutoIncrement"].Value = true;
            otb.Keys.Append("myprimarykey", ADOX.KeyTypeEnum.adKeyPrimary, "recordnum", null, null);

           
            otb.Columns.Append("booknum", ADOX.DataTypeEnum.adVarWChar, 255);


            //允许bookname为空。纯演示目的用。默认情况下adox认为字段应非空。
            otb.Columns.Append("bookname", ADOX.DataTypeEnum.adVarWChar, 255);
            otb.Columns["bookname"].Attributes = ColumnAttributesEnum.adColNullable;
            //设置默认值。 纯演示目的用。
            otb.Columns.Append("pressname", ADOX.DataTypeEnum.adVarWChar, 255);
            otb.Columns["pressname"].ParentCatalog = oCat;
            otb.Columns["pressname"].Properties["default"].Value = "Tsinghua Express";

            oCat.Tables.Append(otb);
            if(oCat.ActiveConnection != null)//看这里。要写上这么一段。
            {
                ADODB.Connection os=(ADODB.Connection) oCat.ActiveConnection;
                os.Close();
            }

            //接下来演示如何写入数据库
            OleDbConnection ocn = new OleDbConnection(ostr);
            ocn = new OleDbConnection(ostr);
            ocn.Open();
            OleDbCommand oledbcommand = new OleDbCommand(@"insert into table1(booknum,bookname) values('book5','Programming visualBplus')", ocn);
            oledbcommand.ExecuteNonQuery();
            ocn.Close();

            ////对部分字段进行赋值。要注意数据库字段名和dataset datatable列名完全一致。
            //OleDbDataAdapter odb = new OleDbDataAdapter("select recordnum, booknum, bookname from table1", ocn);
            //OleDbCommandBuilder odber = new OleDbCommandBuilder(odb);
            //odb.InsertCommand = odber.GetInsertCommand();
            //int i = odb.Update(ods, "odtable");
            //System.Windows.Forms.MessageBox.Show(i.ToString());
            //ocn.Close();
            //ocn = new OleDbConnection(@"provider=microsoft.jet.oledb.4.0;data source=d:\test3.mdb");
            //ocn.Open();
            //OleDbCommand odcom = new OleDbCommand("select count(*) from table1", ocn);
            //int j = (int)odcom.ExecuteScalar();
            //System.Windows.Forms.MessageBox.Show(j.ToString());

        }
    }


    Johnson Dai
    • 已标记为答案 JohnsonDai 2010年12月19日 8:57
    2010年12月19日 8:56