web-dev-qa-db-ja.com

ID列を持つSqlBulkCopy挿入

SqlBulkCopyオブジェクトを使用して、数百万の生成された行をデータベースに挿入しています。唯一の問題は、挿入するテーブルにID列があることです。 SqlBulkCopyOptionsSqlBulkCopyOptions.KeepIdentityに設定し、ID列を0 's、DbNull.Valueおよびnullに設定しようとしました。どれも機能していません。誰かが私に素晴らしいことを教えてくれるなら、私はかなり単純なものを見逃しているように感じます。ありがとう!

編集明確にするために、インポートするDataTableに設定されているID値がありません。インポートの一部として生成されるようにします。

編集2ベースSqlBulkCopyオブジェクトの作成に使用するコードは次のとおりです。

SqlBulkCopy sbc = GetBulkCopy(SqlBulkCopyOptions.KeepIdentity);
sbc.DestinationTableName = LOOKUP_TABLE;

private static SqlBulkCopy GetBulkCopy(SqlBulkCopyOptions options = 
    SqlBulkCopyOptions.Default) 
{
    Configuration cfg = WebConfigurationManager.OpenWebConfiguration("/RSWifi");
    string connString =
    cfg.ConnectionStrings.ConnectionStrings["WifiData"].ConnectionString;
    return new SqlBulkCopy(connString, options);
}
60
FlyingStreudel

宛先テーブルにIDを割り当てるには、SqlBulkCopyOptions.KeepIdentityオプションを使用しないでください。代わりに、ソースからIDをマップしないでください。また、ソースをソースから抽出してSqlBulkCopyに送信しないでください。

36
jason

ColumnMappingオブジェクトの BulkCopy を入力し、ID列をマップしません。 ID列は、ターゲットデータベースによって生成されます。

22
Wim

これは、.NET Coreでそれを解決した方法です(dtはデータテーブルです):

dt.Columns.Cast<DataColumn>().ForEach((c, i) => sqlBulkCopy.ColumnMappings.Add(c.ColumnName, i + 1));

基本的にID(Id)列をスキップするには、宛先列に0ではなく1から始まる序数を割り当てます。

1
silkfire

はい、あなたはSqlBulkCopyOptions.KeepIdentityオプションそれからbulkcopyライターは、このオブジェクトが開始列から書き込むテーブル構造であるとは思わないため、必要に応じて、追加の列を作成するだけでテーブルのIDフィールドを保持するのと同じようにしています。必要な残りの列を持つデータテーブルオブジェクトと、この列にnull値を渡すと、テーブルは自動的にIDを処理します。

1
user2522747

次の2つのオプションがあります-

1-KeepIdentityを使用し、ソースのIdentity値を保持します。

2-Identityフィールドをマップしません。値を割り当てようとしない場合、ターゲットテーブルは自動的に値を割り当てます。

1
JNK

これはテーブルです

CREATE TABLE [dbo].[ProductShippingMethodMap](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ProductId] [int] NOT NULL,
    [ShippingMethodId] [int] NOT NULL,
    [ParentProductId] [int] NOT NULL,
 CONSTRAINT [PK_ProductShippingMethodMap] PRIMARY KEY CLUSTERED 
(
    [Id] 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

以下のC#コードが機能しています

 DataTable dtQtyData = new DataTable();
        dtQtyData.Clear();
        dtQtyData.Columns.Add("Id", typeof(int));

    dtQtyData.Columns.Add("ProductId", typeof(int));
    dtQtyData.Columns.Add("ShippingMethodId", typeof(int));
    dtQtyData.Columns.Add("ParentProductId", typeof(int));


    for (int i = 0; i < ShippingMethodIds.Length; i++)
    {
        for (int j = 0; j < ProductIds.Length; j++)
        {
            var productId = ProductIds[j];
            var shippingMethodId = ShippingMethodIds[i];
            dtQtyData.Rows.Add(new object[] {0,productId, shippingMethodId, parentProductId });
        }

    }
    var connectionString = new DataSettingsManager().LoadSettings().DataConnectionString;
    SqlBulkCopy bulkcopy = new SqlBulkCopy(connectionString, SqlBulkCopyOptions.Default);
    bulkcopy.DestinationTableName = "ProductShippingMethodMap";
    bulkcopy.WriteToServer(dtQtyData);
0
sina_Islam