在我的应用程序中,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
通过将OwnerId
as定义为可为空:
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] 删除。
我来说两句