实体框架中与代码优先外键的更改冲突

Posted

技术标签:

【中文标题】实体框架中与代码优先外键的更改冲突【英文标题】:Conflicting changes with code first foreign key in Entity Framework 【发布时间】:2012-06-11 22:59:23 【问题描述】:

我使用适配器能够将接口而不是具体类型插入 dbcontext。适配器独立工作,但我无法将任何一对一(父子)关系保存到数据库中:

异常来源

public void SaveDomain(IDomain domain)
    _entityRepositor = new Donors();
    _entityRepositor.DomainReps.Add(new DomainRep(domain));                

无效操作异常

Conflicting changes to the role 'DomainRep_TopLevelDomainRep_Target' of the relationship 'Edonics.Repositor.DomainRep_TopLevelDomainRep' have been detected.

外键属性和导航属性应该同步吗?

public class DomainRep: IDomain

    private readonly IDomain _adaptee;        


    public DomainRep(IDomain adaptee)
    
        _adaptee = adaptee;
    

    [NotMapped]
    public IDomain Adaptee
    
        get  return _adaptee; 
    

    public string Id
    
        get  return _adaptee.Id; 
        set  _adaptee.Id = value; 
    

    public string TopLevelDomainRepId
    
        get  return _adaptee.Tld.Id; 

        set  
    

    [ForeignKey("TopLevelDomainRepId")]
    public TopLevelDomainRep TopLevelDomainRep
    
        get  return new TopLevelDomainRep(Tld); 
        set  Tld = value.Adaptee; 
    

    public ITopLevelDomain Tld
    
        get  return _adaptee.Tld; 
        set  _adaptee.Tld = value; 
    

    public string SecondLevelDomainRepId
    
        get  return _adaptee.Sld.Id;   
        
        set   
    

    [ForeignKey("SecondLevelDomainRepId")]
    public SecondLevelDomainRep SecondLevelDomainRep
    
        get  return new SecondLevelDomainRep(Sld); 
        set  Sld = value.Adaptee; 
    

    public ISecondLevelDomain Sld
    
        get  return _adaptee.Sld; 
        set  _adaptee.Sld = value; 
    
    

有什么想法吗?

【问题讨论】:

【参考方案1】:

您的适配器模式会干扰 EF 的工作方式。您正在为实体的导航属性提供不同的实现。例如,如果您多次访问TopLevelDomainRep 属性,它将返回多个实例,但具有相同的 ID/实体键。对于给定的主键值,EF 仅处理每个上下文的单个实例。

要么在 EF 实体之上创建域层,要么按照预期方式使用 EF 实体。

【讨论】:

你是对的 - 我将 TopLevelDomainRep 的 getter 更改为 get return _topLevelDomainRep ?? (_topLevelDomainRep = new TopLevelDomainRep(Tld)); 并开始保存数据/没有例外! (等价于SecondLevelDomainRep

以上是关于实体框架中与代码优先外键的更改冲突的主要内容,如果未能解决你的问题,请参考以下文章

C#检测外键冲突的代码

C#检测外键冲突的代码

带有外键的实体框架选择为空?

在实体优先迁移中为新Guid列添加默认值

实体框架 4.1 代码优先外键 ID

实体框架检测到冲突的更改。尝试使用相同的密钥插入多个实体时可能会发生这种情况