我有这两个实体:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public bool? IsActive { get; set; }
public bool? IsAdmin { get; set; }
public bool? DeletedFlag { get; set; }
public DateTime LastLoginDate { get; set; }
public DateTime CreatedDate { get; set; }
public virtual ICollection<Vote> VoterUser { get; set; }
public virtual ICollection<Vote> VotedUser { get; set; }
}
public class Vote
{
public int Id { get; set; }
public DateTime VoteDate { get; set; }
public int Rate { get; set; }
public int UserId { get; set; }
public int VoterId { get; set; }
public User VotedUser { get; set; }
public User VoterUser { get; set; }
}
并且在流畅的api中定义了这样的外键:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasKey(x => x.Id).Property(x => x.Id).IsRequired();
modelBuilder.Entity<User>().HasMany(x => x.VotedUser).WithRequired(q => q.VotedUser).HasForeignKey(
q => new {q.UserId});
modelBuilder.Entity<User>().HasMany(x => x.VoterUser).WithRequired(q => q.VoterUser).HasForeignKey(
q => new {q.VoterId});
modelBuilder.Entity<Vote>().HasKey(x => x.Id).Property(x => x.Id).IsRequired();
modelBuilder.Entity<Vote>().HasRequired(x => x.VotedUser).WithMany().HasForeignKey(p => p.UserId);
modelBuilder.Entity<Vote>().HasRequired(x => x.VoterUser).WithMany().HasForeignKey(p => p.VoterId);
base.OnModelCreating(modelBuilder);
}
但是当我尝试创建数据库时,我得到了;
“在表格上引入FOREIGN KEY约束'FK_Votes_Users_UserId' “投票”可能会导致周期或多个级联路径。指定ON DELETE 无动作或更新无动作,或修改其他外键 限制。无法创建约束。查看以前的错误。“
我犯了哪个错误?
由于
答案 0 :(得分:0)
您需要将WillCascadeOnDelete(false)添加到投票外键,即:
modelBuilder.Entity<Vote>().HasRequired(x => x.VotedUser).WithMany().HasForeignKey(p => p.UserId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Vote>().HasRequired(x => x.VoterUser).WithMany().HasForeignKey(p => p.VoterId)
.WillCascadeOnDelete(false);
错误消息已经描述了发生了什么。通过在投票和用户之间添加HasMany和HasRequired关系,您可以创建从用户到投票的多个FK,反之亦然。
如果删除一个表中的行,这将导致另一个表上的a cascading delete并再次返回。这可能导致竞争条件,因此SQL Server更喜欢阻止事务而不是导致失控的更改。 您可以通过指定其中一个关系不会导致使用ON DELETE NO ACTION子句进行级联更改来避免这种情况。
在您的情况下,我怀疑主要实体始终是用户,在这种情况下,投票 - >用户关系应使用NO ACTION子句标记。
要使用Fluent API执行此操作,您需要使用WillCascadeOnDelete(false)扩展方法。