32867


# 開発環境

  * Windows 10(64bit)
  * Visual Studio 2015 Update 3
  * C#+WPF
  * プロジェクトに「サービスベースのデータベース(SQL Server)」を追加しています

# 構成

  * 全体の処理ロジックとしては、次の4段階に分かれています 
    * CSVからデータを読み込み
    * それを1行づつ解釈して、空のデータベースに対し`InsertOnSubmit`メソッドを実行
    * `SubmitChanges`メソッドで書き込みを確定する
    * データベースに追記があった際は、その都度CSVにも書き出している
  * データベースは主キーが時刻(`DateTime`)、その他の行が複数の数値データ(`int`)です
  * 上記だけだとデータベースを組む必然性が怪しいですが、主キーで範囲指定(つまり期間指定)を行う予定なのでデータベースを挟んでいます

# 問題が発生した状況

  * データベースに対し`InsertOnSubmit`メソッドは成功しています
  * その後に`SubmitChanges`メソッドを実行しようとすると、`System.Data.Linq.DuplicateKeyException`例外が飛びます
  * 名前から「主キーが重複している」と察せられるが、書き込む前のデータベースの中身が空であることは別途表示用メソッドを用いて確認しています
  * 以上から、どのようにすればエラーが出ず、正常に実行できるのかを知りたいです


CC BY-SA 3.0
2017-02-22T09:44:58.140
32866
2017-02-22T12:28:43.547
12939
question
c# visual-studio
C#でSQL Serverに書き込もうとするとDuplicateKeyExceptionが発生する


エラーからすると単純に主キーの値が重複しているのだと思います。

通常の回避方法としては主キー用の`IDENTITY`属性付き`INT`列を追加し、`datetime`列の方にはインデックスを設定します。このインデックスはクラスター化してもよいです。  
またテーブルを変更したくないのであれば、重複している場合はキー本来の値に`datetime`型の最小精度である3/1000秒ずつ加算するという手もあります。

なお重複データは

[code]

    dataContext.GetChangeSet()
               .Inserts
               .OfType<T>()
               .GroupBy(e => e.Key)
               .Where(g => g.Count() > 1)
               .Select(g => g.Key) // もしくは.SelectMany(g => g)
               .ToList()
    
[/code]

のようなLINQで確認できるかと思います。


CC BY-SA 3.0
2017-02-22T10:32:32.830
32867
2017-02-22T12:28:43.547
2017-02-22T12:28:43.547
5750
5750
32866
answer