如何解决EF中的这种循环依赖

阿杰比文

在我的应用程序中,Agency有个Employees,其中一个是委派给该代理商的所有者:

public class Employee
{
    public int EmployeeId { get; set; }
    public string EmployeeName { get; set; }
    public int EmployerId { get; set; }

    [ForeignKey("EmployerId")]
    public virtual Agency Employer { get; set; }
}

public class Agency
{
    public int AgencyId { get; set; }
    public string AgencyName { get; set; }
    public int OwnerId { get; set; }

    [ForeignKey("OwnerId")]
    public virtual Employee Owner { get; set; }

    [InverseProperty("Employer")]
    public virtual ICollection<Employee> Employees { get; set; }
}

我尝试Agency使用此代码在日期数据库中输入新的代码:

var agency = new Agency();
// ... 

context.Agencies.Add(agency);

var owner = new Employee();
// ...

context.Employees.Add(owner);

owner.Employer = agency;
agency.Owner = owner;

context.SaveChanges();

当我致电时SaveChanges,我收到以下错误,我认为是由于上述循环依赖导致的:

无法确定相关操作的有效顺序。由于外键约束,模型要求或商店生成的值,可能存在依赖关系。

EF中是否可以指定“相关操作”的顺序?或者,是否有更好的方法来编写数据库,以解决此问题,但仍可以对所需的数据结构进行建模?

贫民窟

我不确定是否完全可以在SQL中创建代理和所有者,因为要存储代理,您需要向所有者提供有效的FK,而要存储所有者,则需要向代理提供有效的FK。由于FK约束(除非它们不会被强制执行),因此您不能在不违反约束的情况下存储其中的任何一个。

一种解决方案(并且我不知道另一种解决方案)使其中一种关系成为可选关系,例如,Owner通过将OwnerIdas定义为可为空:

public int? OwnerId { get; set; }

这不会立即解决“有效订购”异常,但是现在您可以存储没有所有者的代理,然后将所有者与已经存储的代理建立关系。要使整个操作“原子化”,您可以将两个必要的调用包装SaveChanges到外部事务中:

using (var tx = new TransactionScope())
{
    var agency = new Agency();

    context.Agencies.Add(agency);

    context.SaveChanges(); // inner transaction 1
    // saves agency with OwnerId = NULL, it wouldn't work with a required owner
    // agency has a primary key from the database now

    var owner = new Employee();

    context.Employees.Add(owner);

    owner.Employer = agency; // sets FK EmployerId to the now known PK of agency
    agency.Owner = owner;

    context.SaveChanges(); // inner transaction 2

    tx.Complete(); // commits the outer transaction
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章