我有一个问题,当我试图添加约束到我的表。我得到了错误:
在表'Employee'上引入外键约束'FK74988DB24B3C886'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他外键约束。
我的约束是在Code表和employee表之间。Code表包含Id, Name, FriendlyName, Type和Value。雇员有许多引用代码的字段,因此每种类型的代码都有一个引用。
我需要字段被设置为空,如果引用的代码被删除。
你知道我该怎么做吗?
我想指出的是(从功能上)SCHEMA和DATA中的循环和/或多条路径之间有很大的区别。虽然DATA中的循环和多路径肯定会使处理复杂化并导致性能问题(“适当”处理的成本),但模式中这些特征的成本应该接近于零。
由于rdb中大多数明显的循环发生在层次结构中(组织结构图、部分、子部分等),不幸的是SQL Server假设了最坏的情况;即,模式周期==数据周期。事实上,如果您使用RI约束,您实际上无法在数据中构建一个循环!
我认为多路径问题与此类似;也就是说,模式中的多条路径并不一定意味着数据中的多条路径,但我对多路径问题的经验较少。
当然,如果SQL Server允许循环,它的深度仍然是32,但这对于大多数情况来说可能已经足够了。(可惜这不是一个数据库设置!)
“代替删除”触发器也不起作用。第二次访问表时,触发器将被忽略。所以,如果你真的想要模拟级联,你就必须在存在循环的情况下使用存储过程。但是,Instead-of-Delete-Trigger适用于多路径情况。
Celko提出了一种“更好的”表示层次结构的方法,这种方法不引入循环,但也有折衷之处。
这是因为员工可能收集其他实体的资格和资格可能有一些其他收集大学
如。
public class Employee{
public virtual ICollection<Qualification> Qualifications {get;set;}
}
public class Qualification{
public Employee Employee {get;set;}
public virtual ICollection<University> Universities {get;set;}
}
public class University{
public Qualification Qualification {get;set;}
}
在DataContext上,它可能如下所示
protected override void OnModelCreating(DbModelBuilder modelBuilder){
modelBuilder.Entity<Qualification>().HasRequired(x=> x.Employee).WithMany(e => e.Qualifications);
modelBuilder.Entity<University>.HasRequired(x => x.Qualification).WithMany(e => e.Universities);
}
在这种情况下,存在从员工到资格,从资格到大学的链条。所以它向我抛出了相同的异常。
我变了之后,这招很管用
modelBuilder.Entity<Qualification>().**HasRequired**(x=> x.Employee).WithMany(e => e.Qualifications);
To
modelBuilder.Entity<Qualification>().**HasOptional**(x=> x.Employee).WithMany(e => e.Qualifications);