SqlBulkCopy
を使用してレコードをデータベースに一括挿入します。SqlBulkCopyがFOREIGN KEY制約エラーを返す
以下はそのコードです。私が気になるのは、SqlBulkCopy
を使用するとFOREIGN KEY制約エラーが発生し、UNION ALL
アプローチを使用するとまったく同じレコードが得られます。私はここで間違って何をしていますか?
CREATE TABLE [dbo].[Kits]
(
[KitId] [nvarchar](15) NOT NULL,
CONSTRAINT [PK_Kits] PRIMARY KEY CLUSTERED ([KitId] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[KitStatuses]
(
[KitStatusId] [int] IDENTITY(1,1) NOT NULL,
[KitId] [nvarchar](15) NOT NULL,
[StatusId] [int] NOT NULL,
[StatusDate] [datetime] NOT NULL,
[IsActiveStatus] [bit] NOT NULL,
CONSTRAINT [PK_KitStatuses] PRIMARY KEY CLUSTERED([KitStatusId] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [IX_KitStatuses_KitId_KitStatus]
UNIQUE NONCLUSTERED ([KitId] ASC, [KitStatusId] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Statuses]
(
[StatusId] [int] IDENTITY(1,1) NOT NULL,
[StatusName] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Statuses] PRIMARY KEY CLUSTERED ([StatusId] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[KitStatuses]
ADD CONSTRAINT [DF_KitStatuses_StatusDate]
DEFAULT (getdate()) FOR [StatusDate]
ALTER TABLE [dbo].[KitStatuses]
ADD CONSTRAINT [DF_KitStatuses_IsActiveStatus]
DEFAULT ((1)) FOR [IsActiveStatus]
ALTER TABLE [dbo].[KitStatuses] WITH CHECK
ADD CONSTRAINT [FK_KitStatuses_Kits]
FOREIGN KEY([KitId]) REFERENCES [dbo].[Kits] ([KitId])
ALTER TABLE [dbo].[KitStatuses] CHECK CONSTRAINT [FK_KitStatuses_Kits]
ALTER TABLE [dbo].[KitStatuses] WITH CHECK
ADD CONSTRAINT [FK_KitStatuses_Statuses]
FOREIGN KEY([StatusId]) REFERENCES [dbo].[Statuses] ([StatusId])
ALTER TABLE [dbo].[KitStatuses] CHECK CONSTRAINT [FK_KitStatuses_Statuses]
私は技術の下に使用しています::DB接続の
- エンタープライズライブラリのデータアクセスブロックの下
public partial class Repository { public bool InsertResult(List<string> kitIds) { if (kitIds == null || kitIds.Count == 0) return false; using (var connection = (SqlConnection)_database.CreateConnection()) { connection.Open(); using (var transaction = connection.BeginTransaction()) { try { using (SqlBulkCopy copy = new SqlBulkCopy(connection, SqlBulkCopyOptions.CheckConstraints, transaction)) { /*This works*/ var sb = new StringBuilder(2048); sb.AppendLine("INSERT INTO KITSTATUSES (KitId, StatusId, IsActiveStatus) "); for (int i = 0; i < kitIds.Count; i++) { sb.AppendLine($"SELECT '{kitIds[i]}', {(int)StatusOfKit.ResultUploaded}, 1"); sb.AppendLine("UNION ALL "); } sb.Remove(sb.Length - 12, 12); connection.Execute(sb.ToString(), null, transaction); /*DOES NOT WORK and throws error: * The INSERT statement conflicted with the FOREIGN KEY constraint "FK_KitStatuses_Kits". The conflict occurred in database "GeneBlueprint", table "dbo.Kits", column 'KitId'. * The statement has been terminated. var kitStatuses = kitIds.Select(k => new KitStatus { KitId = k, IsActiveStatus = true, StatusId = (int)StatusOfKit.ResultUploaded }).ToList(); using (var reader = ObjectReader.Create(kitStatuses, "KitId", "StatusId", "IsActiveStatus")) { //Verify that reader has right values //while (reader.Read()) //{ // Debug.WriteLine($"KitId: {reader.GetFieldValue<string>(0)}, StatusId: {reader.GetFieldValue<int>(1)}, IActiveStatus: {reader.GetFieldValue<bool>(2)}, StatusDate: {reader.GetFieldValue<DateTime>(3)}"); //} copy.DestinationTableName = "KitStatuses"; copy.WriteToServer(reader); } */ /*DOES NOT WORK and throws error * The INSERT statement conflicted with the FOREIGN KEY constraint "FK_KitStatuses_Kits". The conflict occurred in database "GeneBlueprint", table "dbo.Kits", column 'KitId'. * The statement has been terminated. DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn() { ColumnName = "KitId", DataType = typeof(string), MaxLength = 15, AllowDBNull = false, AutoIncrement = false }); dt.Columns.Add(new DataColumn() { ColumnName = "StatusId", DataType = typeof(int), AllowDBNull = false, AutoIncrement = false, DefaultValue = 8 }); dt.Columns.Add(new DataColumn() { ColumnName = "IsActiveStatus", DataType = typeof(bool), AllowDBNull = false, AutoIncrement = false, DefaultValue = true }); for (int i = 0; i < kitIds.Count; i++) { var row = dt.NewRow(); row[0] = kitIds[i]; row[1] = 8; row[2] = true; dt.Rows.Add(row); } using (var reader = ObjectReader.Create(kitStatuses, "KitId", "StatusId", "IsActiveStatus", "StatusDate")) { copy.DestinationTableName = "KitStatuses"; copy.WriteToServer(dt); } */ } transaction.Commit(); } catch (Exception) { transaction.Rollback(); throw; } } } return true; } }
はこの質問に関連するテーブル用のスクリプトです。
- Fast memberは、問題が発生しているのDataReader
が、私は決して新しい問題である可能性があり、そのあなたのコラムの地図。私はマッピングを追加した後、それはちょうど働いた。 – ndd
あなたのシナリオを試してみるととても驚きました。私はいつもアイデンティティ列は無視され、すべてのマッピングが次の列に移されましたが、これは多くの意味をなす必要があります。しかし、私はあなたのコードを試したときに、最初の列だけが最後の列に移動されました。 –