ItemID
PK列と列に一意のインデックスを持つSQLテーブルがありますValue
。
CREATE TABLE [dbo].[Item](
[ItemID] [int] IDENTITY(1,1) NOT NULL,
[Value] [int] NULL
)
CREATE UNIQUE NONCLUSTERED INDEX [IDX_Item_Value_U_NC] ON [dbo].[Item]
(
[Value] ASC
)
linq-sqlを使用して、テーブルに複数のレコード(バッチ挿入/更新)を挿入しています。レコードを挿入する前に「存在する」チェックを行います。
void MultipleInserts(List<int> values)
{
using (var db = new DBDataContext())
{
foreach (var value in values)
{
var dbItem = db.Items
.Where(x => x.Value == value)
.SingleOrDefault();
if (dbItem == null)
{
var Item = new Item()
{
Value = value
};
db.Items.InsertOnSubmit(Item);
}
}
db.SubmitChanges();
}
}
リストに同じ値がある場合、一意のインデックスが原因で以下の例外が発生します。Item
テーブルにレコードがありません。
var values = new List<int>();
values.Add(1);
values.Add(1);
MultipleInserts(values);
例外メッセージ:
一意のインデックス「IDX_Item_Value_U_NC」を持つオブジェクト「dbo.Item」に重複するキー行を挿入できません。
ステートメントは終了されました。
これを回避するにはどうすればよいですか?
編集:単一の挿入を実行できないためdb.SubmitChanges()
、forループ内で呼び出しを移動できません。
EDIT2:これまでに投稿された回答は、linq-sql内の方法ではなく、データの修正を扱っています。intのリストを使用した簡単な例を示しました。しかし実際には、挿入するオブジェクトグラフのリストがあり、すべてのアイテムが挿入/更新のために複数のテーブルにヒットします。回答として投稿したlinq(、、など)を使用する方法をDataContext
見つけましたChangeSet
。DataContext.GetChangeSet().Deletes
DataContext.GetChangeSet().Inserts