代码之家  ›  专栏  ›  技术社区  ›  Ash

sqlbackcopy writetoserver示例。我做错什么了?

  •  0
  • Ash  · 技术社区  · 15 年前

    这可能很长,但我想解释一下我的例子

    我有这个密码:

    #region [parent table]
    DataTable dtParent = new DataTable();
    DataColumn dc;
    
    dc = new DataColumn();
    dc.DataType = System.Type.GetType("System.Int32");
    dc.ColumnName = "Id";
    dc.Unique = true;
    dc.AutoIncrement = true;
    dtParent.Columns.Add(dc);
    
    dc = new DataColumn();
    dc.DataType = System.Type.GetType("System.String");
    dc.ColumnName = "Title";
    dc.Unique = false;
    dtParent.Columns.Add(dc);
    
    dtParent.TableName = "aTestSw";
    dtParent.PrimaryKey = new DataColumn[] { dtParent.Columns[0] };
    #endregion
    
    #region [child table]
    DataTable dtChild = new DataTable();
    
    dc = new DataColumn();
    dc.DataType = System.Type.GetType("System.Int32");
    dc.ColumnName = "Id";
    dc.Unique = true;
    dc.AutoIncrement = true;
    dtChild.Columns.Add(dc);
    
    dc = new DataColumn();
    dc.DataType = System.Type.GetType("System.Int32");
    dc.ColumnName = "ParentId";
    dc.Unique = false;
    dtChild.Columns.Add(dc);
    
    dc = new DataColumn();
    dc.DataType = System.Type.GetType("System.String");
    dc.ColumnName = "Description";
    dc.Unique = false;
    dtChild.Columns.Add(dc);
    
    dtChild.TableName = "aTestSwChild";
    dtChild.PrimaryKey = new DataColumn[] { dtChild.Columns[0] };
    #endregion
    
    DataSet DataSet1 = new DataSet();
    DataSet1.Tables.Add(dtParent);
    DataSet1.Tables.Add(dtChild);
    
    #region [fk]
    DataColumn parentColumn = dtParent.Columns["Id"];
    DataColumn childColumn = dtChild.Columns["ParentId"];
    DataRelation relParentChild = new DataRelation("ParentChild", 
        parentColumn, childColumn);
    DataSet1.Relations.Add(relParentChild); 
    #endregion
    
    #region [fill parent]
    DataRow dr2saveIn = dtParent.NewRow();
    dr2saveIn["Title"] = "a";
    dtParent.Rows.Add(dr2saveIn);
    
    dr2saveIn = dtParent.NewRow();
    dr2saveIn["Title"] = "b";
    dtParent.Rows.Add(dr2saveIn);
    #endregion
    
    #region [fill child]
    dr2saveIn = dtChild.NewRow();
    dr2saveIn["Description"] = "c";
    dr2saveIn["ParentId"] = dtParent.Rows[0]["Id"];
    dtChild.Rows.Add(dr2saveIn);
    
    dr2saveIn = dtChild.NewRow();
    dr2saveIn["Description"] = "d";
    dr2saveIn["ParentId"] = dtParent.Rows[1]["Id"];
    dtChild.Rows.Add(dr2saveIn);   
    #endregion
    
    SqlBulkCopy bulkCopy = new SqlBulkCopy(
        "server=aaa;database=bbb;uid=ccc;password=ddd", 
        SqlBulkCopyOptions.TableLock);
    bulkCopy.DestinationTableName = "dbo.aTestSw";
    bulkCopy.WriteToServer(dtParent);
    bulkCopy.DestinationTableName = "dbo.aTestSwChild";
    bulkCopy.WriteToServer(dtChild);
    

    当我运行它时,在子表的fk列中得到了“看起来”正确的数据。(0和1) 问题是,保存之后,数据会进入数据库,但这并不好。我没有从父表中得到fk id,而是从C代码中得到0和1。 注意:数据库中的表上确实有FK约束。您不能手动添加这些内容,但sqlbackcopy writetoserver没有问题,无论如何都会写入错误的数据(就像没有检查约束一样)

    看表格:

    CREATE TABLE [dbo].[aTestSw](
     [Id] [int] IDENTITY(1,1) NOT NULL,
     [Title] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
     CONSTRAINT [PK_aTestSw] PRIMARY KEY CLUSTERED 
    (
     [Id] ASC
    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]
    
    
    CREATE TABLE [dbo].[aTestSwChild](
     [Id] [int] IDENTITY(1,1) NOT NULL,
     [ParentId] [int] NOT NULL,
     [Description] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
     CONSTRAINT [PK_aTestSwChild] PRIMARY KEY CLUSTERED 
    (
     [Id] ASC
    )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
    ) ON [PRIMARY]
    
    ALTER TABLE [dbo].[aTestSwChild]  WITH NOCHECK ADD  CONSTRAINT [FK_aTestSwChild_aTestSw] FOREIGN KEY([ParentId])
    REFERENCES [dbo].[aTestSw] ([Id])
    
    ALTER TABLE [dbo].[aTestSwChild] CHECK CONSTRAINT [FK_aTestSwChild_aTestSw]
    

    结果如下:

    select * from aTestSw
    
    Id          Title
    16          a
    17          b
    
    select * from aTestSwChild
    
    Id          ParentId    Description
    12          0           c
    13          1           d
    

    我做错什么了? 也许我不应该在C里得到这样的身份证。但是如何呢? 还是可能?我的意思是,我的第二个BulkInsert如何知道SQL!!!!身份证在插入?

    2 回复  |  直到 12 年前
        1
  •  1
  •   masoud ramezani    15 年前

    使用此选项:

    SqlBulkCopyOptions.KeepIdentity
    

    在执行大容量复制操作之前,请将数据库的checkConstraints设置为off。在此之后,使用大容量复制插入数据。完成所有工作后,将checkConstraints设置为on。

    upside选项强制数据库保留您的标识值。

        2
  •  0
  •   jhilden    12 年前

    默认情况下,sqlblkcopy会将您的外键转换为nocheck外键。您需要添加选项 SqlBulkCopyOptions.CheckConstraints 为了保持您的外键检查所有现有和所有新数据。