实体框架Code First - 在对象“dbo.T_CRProviders”中无法插入重复键

4

我有一些紧急问题,网上找不到答案。

我正在使用CodeFirst EF 4.3.1,出现了一个错误:

违反 PRIMARY KEY 约束条件 'PK_T_CRProviders'。无法将重复键插入对象 '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(主键),Name

表 T_CRSupportedResources 的结构如下:SupportedResourceId(主键),Provider_Enum(外键)。

在数据库表 T_CRProviders 中,我已经有一个具有以下值的提供商:

Enum: 0 (which is PE_Abcd)
Name: "PE_Abcd"

现在我的main()方法调用AddSupportedResource方法。该方法向表T_CRSupportedResources中添加一个新的CRSupportedResource,该资源引用提供者0(PE_Abcd)。该方法如下:

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_CRSupportedResources时不更新表T_CRProviders

顺便提一下,在SQL Server中,我看到表T_CRSupportedResources有一个名为FK_RW_TCRSupportedCloudResources_RW_TCRCloudProviders_Provider_Enum的外键,其更新规则的值为无操作

2个回答

6
我希望这种方法将不会影响表T_CRProviders,而是向表T_CRSupportedResources添加一行新记录。
不会发生。您正在创建一个由现有实体a和新实体组成的分离实体图。EF在您通知它之前不知道实体的存在-没有进行EF后台验证存在的DB查询。
如果您调用Add方法,则您实体图中的所有实体都将被视为新的。如果您不想插入它们中的所有实体,可以使用Attach并手动更改新实体的状态。例如:
myContext.CRSupportedResources.Attach(supportedResource);
myContext.Entry(supportedResource).State = EntityState.Added;

0

4
这是另一种更糟糕的解决方案,因为您需要额外的往返数据库来获取您已经知道的记录... - Ladislav Mrnka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接