【问题标题】:Introducing Foreign key Constraint on table may cause cycles or multiple cascade paths在表上引入外键约束可能会导致循环或多个级联路径
【发布时间】:2015-10-26 02:23:41
【问题描述】:

我已经发现了许多其他类似的问题,但我不确定为什么它会在我的实体上这样做。用简单的英语表示以下表示。三个实体,帐户、站点和合同。一个帐户可以有多个站点。一个账户可以有多个合约。一个站点可以有多个合同。因此,在某些情况下,您可以将合同附加到网站,然后将其附加到帐户或直接附加到帐户的合同。

我假设我得到了这个,因为删除合同有两种可能的级联,要么是在删除帐户时级联并直接附加到帐户,要么是在网站被级联时删除。

我认为合同中既不需要 AccountId 也不需要 SiteId,这不应该触发错误。我想要做的是将合同附加到站点(然后是帐户)或将合同直接附加到帐户 - 但我仍然想维护数据库引用完整性。

Introducing FOREIGN KEY constraint 'FK_dbo.Contract_dbo.Site_SiteId' on table 'Contract' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

我的班级/实体:

帐户

public partial class Account
{
    public int Id { get; set; }

    [Display(Name = "Account Name")]
    [Required]
    [MinLength(3, ErrorMessage = "The Account Name should be at least 3 characters")]
    [MaxLength(40, ErrorMessage = "The Account Name should be no more than 40 characters")]
    [Remote("IsAccountNameAvailable", "Helper", ErrorMessage = "This Account name already exists, please try another name")]
    public string AccountName { get; set; }

    [ScaffoldColumn(false)]
    [Display(Name = "Date Account Added")]
    public DateTime DateAdded { get; set; }

    public virtual ICollection<Site> Sites { get; set; }
    public virtual ICollection<Contract> Contracts { get; set; }
}

网站

public partial class Site
{
    public int Id { get; set; }

    [Required(ErrorMessage = "A site must be attached to an account - please specify an account")]
    [Display(Name = "Parent Account")]
    public int AccountId { get; set; }

    [Display(Name = "Site Name")]
    [Required]
    [MinLength(3, ErrorMessage = "The Site Name should be at least 3 characters")]
    [MaxLength(40, ErrorMessage = "The Site Name should be no more than 40 characters")]
    public string SiteName { get; set; }

    [ScaffoldColumn(false)]
    public DateTime DateAdded { get; set; }

    [Required]
    [Display(Name = "Primary Site")]

    //[Remote("IsThereAlreadyAPrimarySite", "Helper", AdditionalFields = "AccountId", ErrorMessage = "There is already a primary site set for this account", HttpMethod = "POST")]
    public bool PrimarySite { get; set; }

    [Display(Name = "Site Notes")]
    [Column(TypeName = "text")]
    public string SiteNotes { get; set; }

    public virtual Account Account { get; set; }

    public virtual ICollection<Contract> Contracts { get; set; }

}

合同

public partial class Contract
{
    public int Id { get; set; }

    public int AccountId { get; set; }
    public int SiteId { get; set; }

    [Display(Name = "Contract Type")]
    [Required]
    public int ContractTypeId { get; set; }

    public virtual Account Account { get; set; }

    public virtual Site Site { get; set; }

    public virtual ContractType ContractType { get; set; }

}

【问题讨论】:

    标签: c# asp.net asp.net-mvc entity-framework ef-code-first


    【解决方案1】:

    在您的DbContext 文件覆盖方法OnModelCreating 中,必须将至少一个关系配置为不删除时级联。这种关系必须在删除时明确处理

    protected override void OnModelCreating( DbModelBuilder modelBuilder )
    {
        base.OnModelCreating( modelBuilder );
    
        modelBuilder.Entity<Contract>()
            .HasRequired( c => c.Site)
            .WithMany( s => s.Contracts )
            .WillCascadeOnDelete( false );
    }
    

    【讨论】:

    • 这行得通,但 HasRequired 是否意味着合同明确需要网站?
    • 是的。但是如果你需要可选的关系,也有 HasOptional 方法。
    猜你喜欢
    • 2010-10-25
    • 2020-10-27
    • 2011-05-08
    • 2013-10-22
    相关资源
    最近更新 更多