Entity Framework Code First - オブジェクト 'dbo.T_CRProviders' に重複キーを挿入できません
-
12-12-2019 - |
質問
緊急の問題があり、ウェブ上で答えが見つかりませんでした。
CodeFirst EF 4.3.1 を使用していますが、エラーが発生します。Violation of PRIMARY KEY constraint 'PK_T_CRProviders'. Cannot insert duplicate key in object 'dbo.T_CRProviders'.
私のコードは次のとおりです:
モデル:
public enum CRProviderEnums
{
PE_Abcd = 0,
PE_Efgh
}
[Table("T_CRProviders")]
public class CRProvider
{
[Key]
[Required]
public int Enum { get; set; }
[Required]
public string Name { get; set; }
}
[Table("T_CRSupportedResources")]
public class CRSupportedResource
{
[Key]
public Guid SupportedResourceId { get; set; }
[Required]
public CRProvider Provider { get; set; }
}
Dbコンテキスト:
public class RSContext : DbContext
{
public DbSet<CRProvider> CRProviders { get; set; }
public DbSet<CRSupportedResource> CRSupportedResources { get; set; }
}
テーブル T_CRProviders は次のようになります。 Enum (PK), Name
テーブル T_CRSupportedResources は次のようになります。 SupportedResourceId (PK), Provider_Enum (FK).
データベース テーブル T_CRProviders には、次の値を持つプロバイダーがすでにあります。
Enum: 0 (which is PE_Abcd)
Name: "PE_Abcd"
ここで、main() がメソッド AddSupportedResource を呼び出します。このメソッドは、プロバイダ 0 (PE_Abcd) を参照する新しい CRSupportedResource をテーブル T_CRSupportedResources に追加します。メソッドは次のようになります。
public void AddSupportedResource()
{
CRSupportedResource supportedResource = new CRSupportedResource()
{
SupportedResourceId = Guid.NewGuid(),
Provider = new CRProvider()
{
Enum = (int)CRProviderEnums.PE_Abcd,
Name = "PE_Abcd"
}
};
using (RSContext myContext = new RSContext())
{
myContext.CRSupportedResources.Add(supportedResource);
myContext.SaveChanges();
}
}
このメソッドはテーブル T_CRProviders をそのままにし、次のような新しい行をテーブル T_CRSupportedResources に追加すると予想します。
SupportedResourceId: DE532083-68CF-484A-8D2B-606BC238AB61
Provider_Enum (FK): 0 (which is PE_Abcd).
代わりに、SaveChanges 時に Entity Framework も Provider を T_CRProviders テーブルに追加しようとしますが、そのようなプロバイダーは既に存在するため、次の例外がスローされます。
An error occurred while updating the entries.
Violation of PRIMARY KEY constraint 'PK_T_CRProviders'. Cannot insert duplicate key in object 'dbo.T_CRProviders'.
The statement has been terminated.
私の質問:
テーブルを更新しないようにEFに指示するにはどうすればよいですか T_CRProviders
テーブル更新時 T_CRSupportedResources
?
ところで、SQL Server にはそのテーブルが表示されます T_CRSupportedResources
という名前の外部キーがあります FK_RW_TCRSupportedCloudResources_RW_TCRCloudProviders_Provider_Enum
その更新ルールの値は次のとおりです。 No Action
.
解決 2
実はこれを行う方法があります。
私の質問に対する答えは次のリンクを参照してください。
他のヒント
この方法は、テーブルT_CRProvidersを触れずに残し、テーブルT_CRSUPPORTEDRESOURCESに新しい行を追加することを期待しています
いいえ、そんなことはありません。既存のエンティティ a と新しいエンティティから構成される分離エンティティ グラフを作成しています。EF は、エンティティの存在について通知されるまで知りません。EF によって背後で実行される、存在を検証する DB クエリはありません。
電話したら Add
このメソッドでは、エンティティ グラフ内のすべてのエンティティが新規として追加されます。すべてを挿入したくない場合は、以下を使用して始めることができます Attach
そして手動で状態を新しいものに変更します。たとえば次のようになります。
myContext.CRSupportedResources.Attach(supportedResource);
myContext.Entry(supportedResource).State = EntityState.Added;