【问题标题】:EF Code First entity relationship issueEF Code First 实体关系问题
【发布时间】:2023-03-12 12:20:01
【问题描述】:

我刚开始使用 EF CF(来自 PHP/MySQL 领域),我希望有人能帮助我理解我在这里做错了什么。

使用那里的许多优秀教程,我创建了具有关系的模型类,并且数据库正在创建和更新中。但现在我遇到了级联删除问题。

据我了解,这是因为可以通过级联删除删除实体,而不仅仅是创建孤立记录 - 对吗?

public class jbsEntity
{
    [Timestamp]
    public Byte[] TimeStamp { get; set; }

    //public User CreatedBy { get; set; }
    //public User UpdatedBy { get; set; }
}

public class Customer : jbsEntity
{
    public int Id { get; set; }
    public string Salutation { get; set; }

    [Required, StringLength(128)]
    public string FirstName { get; set; }

    [Required, StringLength(128)]
    public string LastName { get; set; }

    public string BillingName { get; set; }

    [Required, StringLength(128)]
    public string Address { get; set; }

    [Required, StringLength(128)]
    public string Suburb { get; set; }

    [Required, StringLength(4)]
    public string Postcode { get; set; }

    public string BillingAddress { get; set; }
    public string BillingSuburb { get; set; }
    public string BillingPostcode { get; set; }

    public virtual List<Contact> Contacts { get; set; }

    public virtual List<Residence> Residences { get; set; }

}

public class Residence : jbsEntity
{
    public int Id { get; set; }

    [Required, StringLength(128)]
    public string Name { get; set; }

    [Required, StringLength(128)]
    public string Address { get; set; }

    [Required, StringLength(128)]
    public string Suburb { get; set; }

    [Required, StringLength(4)]
    public string Postcode { get; set; }

    public bool Active { get; set; }
    public string AccessInstructions { get; set; }
    public string ServiceFrequency { get; set; }
    public string RegularServiceCost { get; set; }

    [Required]
    public int CustomerId { get; set; }
    public virtual Customer Customer { get; set; }

    public virtual List<Contact> Contacts { get; set; }

    public virtual List<Pool> Pools { get; set; }

    public virtual List<Job> Jobs { get; set; }

    public virtual List<Image> Images { get; set; }

}

public class Pool : jbsEntity
{
    public int Id { get; set; }

    [Required, StringLength(128)]
    public string Name { get; set; }

    [Required, StringLength(128)]
    public string Size { get; set; }
    public string AccessInstructions { get; set; }
    public string SurfcaceType { get; set; }
    public bool Indoor { get; set; }
    public decimal TargetPH { get; set; }
    public decimal TargetIron { get; set; }
    public decimal TargetCopper { get; set; }
    public decimal TargetCalcium { get; set; }
    public decimal TargetChlorine { get; set; }
    public decimal TargetAlkaline { get; set; }
    public decimal TargetStabiliser { get; set; }

    [Required]
    public int ResidenceId { get; set; }
    public virtual Residence Residence { get; set; }

    public virtual List<JobService> JobServices { get; set; }

    public virtual List<Image> Images { get; set; }

}

public class Equipment : jbsEntity
{
    public int Id { get; set; }

    [Required, StringLength(128)]
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime Installed { get; set; }
    public DateTime WarrantyExpiration { get; set; }
    public string Status { get; set; }

    [Required]
    public int PoolId { get; set; }
    public virtual Pool Pool { get; set; }

    public virtual List<Image> Images { get; set; }

}

public class Contact : jbsEntity
{
    public int Id { get; set; }
    public string Salutation { get; set; }

    [Required, StringLength(128)]
    public string FirstName { get; set; }

    [Required, StringLength(128)]
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Mobile { get; set; }
    public string Phone { get; set; }

}

public class Image : jbsEntity
{
    public int Id { get; set; }
    public string FileName { get; set; }
    public string FilePath { get; set; }
    public string MimeType { get; set; }
}

public class Job : jbsEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string InvoiceNumber { get; set; }
    public string Comments { get; set; }
    public string CompletionNotes { get; set; }
    public string DpscActionRequired { get; set; }
    public string WorkPerformed { get; set; }
    public string NextCallInstruction { get; set; }
    public bool ServiceComplete { get; set; }
    public DateTime DueDate { get; set; }
    public DateTime ScheduledDate { get; set; }
    public DateTime CompletionDate { get; set; }

    [Required]
    public int ResidenceId { get; set; }
    public virtual Residence Residence { get; set; }

    public virtual List<JobService> JobServices { get; set; }

    public virtual List<Image> Images { get; set; }

}

public class JobService : jbsEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool SkimSurface { get; set; }
    public bool BrushWalls { get; set; }
    public bool Vacuum { get; set; }
    public bool BackwashRinse { get; set; }
    public bool EmptyBaskets { get; set; }
    public bool CleanElectrodes { get; set; }
    public bool BalanceWater { get; set; }
    public bool AddedAcid { get; set; }
    public bool AddedClarifier { get; set; }
    public bool SwimClearOnsite { get; set; }
    public decimal PH { get; set; }
    public decimal Iron { get; set; }
    public decimal Copper { get; set; }
    public decimal Calcium { get; set; }
    public decimal Chlorine { get; set; }
    public decimal Alkaline { get; set; }
    public decimal Stabiliser { get; set; }

    [Required]
    public int JobId { get; set; }
    public virtual Job Job { get; set; }

    [Required]
    public int PoolId { get; set; }
    public virtual Pool Pool { get; set; }

    public virtual List<Image> Images { get; set; }

}


public class User : jbsEntity
{
    public int Id { get; set; }
    [Required]
    public string UserName { get; set; }
    [Required]
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    [Required]
    public string Password { get; set; }
    [Required, Compare("Password")]
    public string ComparePassword { get; set; }
}

我得到这个错误:

{"Introducing FOREIGN KEY constraint 'Pool_Residence' on table 'Pools' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.\r\nCould not create constraint. See previous errors."}

我认为导致问题的关系是:

Customer -> Residences -> Pools
Job -> JobServices
Residence -> Jobs
Pools -> JobServices

谁能帮助我了解我做错了什么以及如何解决它?也欢迎任何其他建议!

提前致谢。

【问题讨论】:

    标签: .net entity-framework-4 ef-code-first


    【解决方案1】:

    实际上你没有做错任何事,但 SQL Server 不喜欢处理多个级联删除路径。从ResidencePool实际上有两条删除路径。

    1. 直接关系,以及
    2. 通过Residence -> Job -> JobService -> Pool

    在您的模型中,所有外键列都不可为空。因此 EF 尝试使用级联删除创建 FK。

    为避免该问题,使其中一个 FK 可以为空,并通过存储过程、触发器、直通代码等替代机制处理子实体的删除。

    【讨论】:

    • 谢谢埃兰加。这是有道理的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多