我有一些紧急问题,在网上找不到答案。
我正在使用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。此方法将引用提供程序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框架还试图将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.
我的问题:
在更新表T_CRSupportedResources
时,我如何指示EF不更新表T_CRProviders
?
顺便说一句,在SQL Server中,我看到表T_CRSupportedResources
有一个名为FK_RW_TCRSupportedCloudResources_RW_TCRCloudProviders_Provider_Enum
的外键,其更新规则的值为No Action
。
我期望该方法将不影响表T_ CRProviders,并向表T_CRSupportedResources 添加新行
不,这不会发生。您正在创建由现有实体a和新实体组成的分离实体图。EF在你通知它之前并不知道你的实体的存在——EF在后台执行的DB查询不会验证它的存在。
如果调用Add
方法,则实体图中的所有实体都将作为新实体添加。如果您不想插入所有的,您可以从使用Attach
开始,并手动更改新的状态。例如:
myContext.CRSupportedResources.Attach(supportedResource);
myContext.Entry(supportedResource).State = EntityState.Added;
实际上,有一种方法可以做到这一点。
请参阅以下链接中我的问题的答案:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/62f3e5bc-c972-4622-b830-e7d7fe710101