2012-03-12 39 views
4

中插入重複密鑰我有一些緊迫的問題,我無法通過網絡找到答案。實體框架代碼優先 - 不能在對象'dbo.T_CRProviders'

我使用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; } 
} 

的DbContext:

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。此方法向表T_CRSupportedResources添加引用提供程序0(PE_Abcd)的新CRSupportedResource。該方法是這樣的:

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,實體框架還試圖提供程序添加到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. 

我的問題:

如何在更新表T_CRSupportedResources時指示EF不更新表T_CRProviders

順便說一句,在SQL Server中,我看到表T_CRSupportedResources有一個名爲FK_RW_TCRSupportedCloudResources_RW_TCRCloudProviders_Provider_Enum的外鍵,其更新規則的值爲No Action

回答

6

I expect that this method will leave table T_CRProviders untouched, and add a new row to table T_CRSupportedResources

不,它不會發生。您正在創建由現有實體a和新實體組成的分離實體圖。在你通知它之前,EF並不知道你的實體的存在 - 沒有數據庫查詢證實EF在後面執行存在。

如果您致電Add方法,則實體圖中的所有實體都將添加爲新的。如果您不想插入所有這些文件,您可以先使用Attach並手動更改新文件的狀態。例如:

myContext.CRSupportedResources.Attach(supportedResource); 
myContext.Entry(supportedResource).State = EntityState.Added; 
+0

偉大的答案! 謝謝! – mayash 2012-03-13 14:03:25