【问题标题】: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; }
    }
    
}

有什么想法吗?

【问题讨论】:

    标签: c# .net sql entity-framework orm


    【解决方案1】:

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

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

    【讨论】:

    • 你是对的 - 我将 TopLevelDomainRep 的 getter 更改为 get { return _topLevelDomainRep ?? (_topLevelDomainRep = new TopLevelDomainRep(Tld)); } 并开始保存数据/没有例外! (等价于SecondLevelDomainRep
    猜你喜欢
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 2015-02-24
    • 2021-01-05
    相关资源
    最近更新 更多