如何告诉 Entity Framework 级联删除会起作用

问题描述 投票:0回答:0

Entity Framework 发现可能存在竞争级联删除。但是,在使用中这是不可能的。我需要知道如何告诉实体框架这个。

此应用程序用于处理政治志愿者,这些志愿者可以在州级、县级和/或竞选级别提供帮助。

  1. 每个州都有一系列县和活动。
  2. 每个州、县和竞选活动都有一系列事件。
  3. 每个事件都有一个父/所有者,它是州、县或竞选活动。对于任何给定的事件,只设置其中一个。

我看到两个问题(也许还有更多)。

  1. 如果你从事件追踪到它的三个所有者,那么这三个所有者都有一个事件集合。
  2. 如果你从州追踪,它有一个事件集合,它还有一个县和活动的集合,每个都有一个事件集合。

我如何告诉 Entity Framework 和 SQL Server 在操作中不会有两个所有者都试图级联删除同一个事件?

相关问题。在 EventConfiguration.Configure 中,我如何告诉 DB 对于三个外键强制执行,在任何给定记录中,其中两个外键必须为空?

我运行 Update-Database 的错误是:

Microsoft.Data.SqlClient.SqlException (0x80131904): Introducing FOREIGN KEY constraint 'FK_Events_Counties_CountyId' on table 'Events' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

解决方案在此处作为 zip 提供。 或者您可以查看以下课程:

public class Campaign
{
    public int Id { get; private set; }
    public string Name { get; private set; }
    public required State State { get; set; }
    public ICollection<Event> Events { get; set; }
    public ICollection<User> Followers { get; set; }
    protected Campaign(int id, string name, DateTime created)
    {
        Id = id;
        Events = default!;
        Followers = default!;
    }
    public Campaign()
    {
        Events = new List<Event>();
        Followers = new List<User>();
    }
}

public class CampaignConfiguration : IEntityTypeConfiguration<Campaign>
{
    public void Configure(EntityTypeBuilder<Campaign> builder)
    {
        builder.HasIndex(new[] { "Name", "StateId" }).IsUnique();
        builder.HasIndex("StateId");
        builder.HasMany(x => x.Events)
            .WithOne(x => x.Campaign).OnDelete(DeleteBehavior.Cascade);
    }
}


public class County
{
    public int Id { get; private set;  }
    public string Name { get; private set; }
    public required State State { get; set; }
    public ICollection<Event> Events { get; set; }
    public ICollection<User> Followers { get; set; }
    protected County(int id, string name)
    {
        Id = id;
        Events = default!;
        Followers = default!;
    }
    public County()
    {
        Events = new List<Event>();
        Followers = new List<User>();
    }
}

public class CountyConfiguration : IEntityTypeConfiguration<County>
{
    public void Configure(EntityTypeBuilder<County> builder)
    {
        builder.HasIndex(new[]{"Name", "StateId"}).IsUnique();
        builder.HasMany(x => x.Events)
            .WithOne(x => x.County).OnDelete(DeleteBehavior.Cascade);
    }
}


public class Event
{
    public int Id { get; private set; }
    public required User Owner { get; set; }
    public Campaign? Campaign { get; set; }
    public County? County { get; set; }
    public State? State { get; set; }
    protected Event(int id, DateTime created)
    {
        Id = id;
    }
    public Event()
    {
    }
}

public class EventConfiguration : IEntityTypeConfiguration<Event>
{
    public void Configure(EntityTypeBuilder<Event> builder)
    {
        // fails!
        // builder.HasIndex(e => new[] { "CampaignId", "CountyId", "StateId" }).IsUnique();
    }
}


public class State
{
    public int Id { get; private set; }
    public string Name { get; private set; }
    public ICollection<County> Counties { get; set; }
    public ICollection<Campaign> Campaigns { get; set; }
    public ICollection<Event> Events { get; set; }
    public ICollection<User> Followers { get; set; }
    protected State(int id, string name)
    {
        Id = id;
        Counties = default!;
        Campaigns = default!;
        Events = default!;
        Followers = default!;
    }
    public State()
    {
        Counties = new List<County>();
        Campaigns = new List<Campaign>();
        Events = new List<Event>();
        Followers = new List<User>();
    }
}

public class StateConfiguration : IEntityTypeConfiguration<State>
{
    public void Configure(EntityTypeBuilder<State> builder)
    {
        builder.HasMany(x => x.Counties)
            .WithOne(x => x.State).OnDelete(DeleteBehavior.Cascade);
        builder.HasMany(x => x.Campaigns)
            .WithOne(x => x.State).OnDelete(DeleteBehavior.Cascade);
        builder.HasMany(x => x.Events)
            .WithOne(x => x.State).OnDelete(DeleteBehavior.Cascade);
    }
}


public class User
{
    public int Id { get; private set; }
    public ICollection<Campaign> Campaigns { get; set; }
    public ICollection<County> Counties { get; set; }
    public ICollection<State> States { get; set; }
    public ICollection<Event> Events { get; set; }
    protected User(int id, string name, string email)
    {
        Id = id;
        Campaigns = default!;
        Counties = default!;
        States = default!;
        Events = default!;
    }
    public User()
    {
        Campaigns = new List<Campaign>();
        Counties = new List<County>();
        States = new List<State>();
        Events = new List<Event>();
    }
}

public class UserConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
    }
}
entity-framework entity-framework-core
© www.soinside.com 2019 - 2024. All rights reserved.