微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

EF Core:SQLite 删除不是级联的

如何解决EF Core:SQLite 删除不是级联的

我正在尝试使用 sqlite 和 Entity Framework Core 将数据库添加到我的 WPF 应用程序。除了 .Remove() 调用之外,一切似乎都正常工作,该调用按预期删除元素,但不会级联到其他表。

上下文类:

public class PersistenceContext : DbContext
{
    public DbSet<Server> Servers { get; set; }
    public DbSet<Network> Networks { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseLazyLoadingProxies();
        optionsBuilder.Usesqlite("foreign keys=true;Data Source=" + Path.Combine(App.ApplicationPath,"persistence","data.db"));
        optionsBuilder.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole()));

        base.OnConfiguring(optionsBuilder);
    }
}

remove 方法调用

public void RemoveEntity(Entity entity)
    {
        lock (persistenceContext)
        {
            switch (entity)
            {
                case Server server:
                    persistenceContext.Servers.Remove(server);
                    break;
                case Network network:
                    persistenceContext.Networks.Remove(network);
                    break;
            }
            persistenceContext.SaveChanges();
        }
    }

Add-Migration Initial 生成的迁移类:

public partial class InitialCreate : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(
            name: "JavaSettings",columns: table => new
            {
                Id = table.Column<int>(type: "INTEGER",nullable: false)
                    .Annotation("sqlite:Autoincrement",true),MaxRam = table.Column<int>(type: "INTEGER",nullable: false),JavaPath = table.Column<string>(type: "TEXT",nullable: true),StartupParameters = table.Column<string>(type: "TEXT",nullable: true)
            },constraints: table =>
            {
                table.PrimaryKey("PK_JavaSettings",x => x.Id);
            });

        migrationBuilder.CreateTable(
            name: "ServerVersion",Type = table.Column<int>(type: "INTEGER",Version = table.Column<string>(type: "TEXT",Build = table.Column<int>(type: "INTEGER",JarLink = table.Column<string>(type: "TEXT",constraints: table =>
            {
                table.PrimaryKey("PK_ServerVersion",x => x.Id);
            });

        migrationBuilder.CreateTable(
            name: "SimpleTime",Hours = table.Column<int>(type: "INTEGER",Minutes = table.Column<int>(type: "INTEGER",nullable: false)
            },constraints: table =>
            {
                table.PrimaryKey("PK_SimpleTime",x => x.Id);
            });

        migrationBuilder.CreateTable(
            name: "Networks",columns: table => new
            {
                UID = table.Column<string>(type: "TEXT",Name = table.Column<string>(type: "TEXT",ProxyType = table.Column<int>(type: "INTEGER",JavaSettingsId = table.Column<int>(type: "INTEGER",SyncServers = table.Column<bool>(type: "INTEGER",Initialized = table.Column<bool>(type: "INTEGER",StartWithFork = table.Column<bool>(type: "INTEGER",ServerIconId = table.Column<int>(type: "INTEGER",VersionId = table.Column<int>(type: "INTEGER",constraints: table =>
            {
                table.PrimaryKey("PK_Networks",x => x.UID);
                table.ForeignKey(
                    name: "FK_Networks_JavaSettings_JavaSettingsId",column: x => x.JavaSettingsId,principalTable: "JavaSettings",principalColumn: "Id",onDelete: referentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_Networks_ServerVersion_VersionId",column: x => x.VersionId,principalTable: "ServerVersion",onDelete: referentialAction.Cascade);
            });

        migrationBuilder.CreateTable(
            name: "RestartTime",Enabled = table.Column<bool>(type: "INTEGER",TimeId = table.Column<int>(type: "INTEGER",constraints: table =>
            {
                table.PrimaryKey("PK_RestartTime",x => x.Id);
                table.ForeignKey(
                    name: "FK_RestartTime_SimpleTime_TimeId",column: x => x.TimeId,principalTable: "SimpleTime",onDelete: referentialAction.Cascade);
            });

        migrationBuilder.CreateTable(
            name: "StartTime",constraints: table =>
            {
                table.PrimaryKey("PK_StartTime",x => x.Id);
                table.ForeignKey(
                    name: "FK_StartTime_SimpleTime_TimeId",onDelete: referentialAction.Cascade);
            });

        migrationBuilder.CreateTable(
            name: "StopTime",constraints: table =>
            {
                table.PrimaryKey("PK_StopTime",x => x.Id);
                table.ForeignKey(
                    name: "FK_StopTime_SimpleTime_TimeId",onDelete: referentialAction.Cascade);
            });

        migrationBuilder.CreateTable(
            name: "Servers",AutoSetSha1 = table.Column<bool>(type: "INTEGER",ResourcePackHashAge = table.Column<DateTime>(type: "TEXT",Restart1Id = table.Column<int>(type: "INTEGER",Restart2Id = table.Column<int>(type: "INTEGER",Restart3Id = table.Column<int>(type: "INTEGER",Restart4Id = table.Column<int>(type: "INTEGER",AutoStop1Id = table.Column<int>(type: "INTEGER",AutoStop2Id = table.Column<int>(type: "INTEGER",AutoStart1Id = table.Column<int>(type: "INTEGER",AutoStart2Id = table.Column<int>(type: "INTEGER",constraints: table =>
            {
                table.PrimaryKey("PK_Servers",x => x.UID);
                table.ForeignKey(
                    name: "FK_Servers_JavaSettings_JavaSettingsId",onDelete: referentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_Servers_RestartTime_Restart1Id",column: x => x.Restart1Id,principalTable: "RestartTime",onDelete: referentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_Servers_RestartTime_Restart2Id",column: x => x.Restart2Id,onDelete: referentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_Servers_RestartTime_Restart3Id",column: x => x.Restart3Id,onDelete: referentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_Servers_RestartTime_Restart4Id",column: x => x.Restart4Id,onDelete: referentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_Servers_ServerVersion_VersionId",onDelete: referentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_Servers_StartTime_AutoStart1Id",column: x => x.AutoStart1Id,principalTable: "StartTime",onDelete: referentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_Servers_StartTime_AutoStart2Id",column: x => x.AutoStart2Id,onDelete: referentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_Servers_StopTime_AutoStop1Id",column: x => x.AutoStop1Id,principalTable: "StopTime",onDelete: referentialAction.Cascade);
                table.ForeignKey(
                    name: "FK_Servers_StopTime_AutoStop2Id",column: x => x.AutoStop2Id,onDelete: referentialAction.Cascade);
            });

        migrationBuilder.CreateIndex(
            name: "IX_Networks_JavaSettingsId",table: "Networks",column: "JavaSettingsId");

        migrationBuilder.CreateIndex(
            name: "IX_Networks_VersionId",column: "VersionId");

        migrationBuilder.CreateIndex(
            name: "IX_RestartTime_TimeId",table: "RestartTime",column: "TimeId");

        migrationBuilder.CreateIndex(
            name: "IX_Servers_AutoStart1Id",table: "Servers",column: "AutoStart1Id");

        migrationBuilder.CreateIndex(
            name: "IX_Servers_AutoStart2Id",column: "AutoStart2Id");

        migrationBuilder.CreateIndex(
            name: "IX_Servers_AutoStop1Id",column: "AutoStop1Id");

        migrationBuilder.CreateIndex(
            name: "IX_Servers_AutoStop2Id",column: "AutoStop2Id");

        migrationBuilder.CreateIndex(
            name: "IX_Servers_JavaSettingsId",column: "JavaSettingsId");

        migrationBuilder.CreateIndex(
            name: "IX_Servers_Restart1Id",column: "Restart1Id");

        migrationBuilder.CreateIndex(
            name: "IX_Servers_Restart2Id",column: "Restart2Id");

        migrationBuilder.CreateIndex(
            name: "IX_Servers_Restart3Id",column: "Restart3Id");

        migrationBuilder.CreateIndex(
            name: "IX_Servers_Restart4Id",column: "Restart4Id");

        migrationBuilder.CreateIndex(
            name: "IX_Servers_VersionId",column: "VersionId");

        migrationBuilder.CreateIndex(
            name: "IX_StartTime_TimeId",table: "StartTime",column: "TimeId");

        migrationBuilder.CreateIndex(
            name: "IX_StopTime_TimeId",table: "StopTime",column: "TimeId");
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Networks");

        migrationBuilder.DropTable(
            name: "Servers");

        migrationBuilder.DropTable(
            name: "JavaSettings");

        migrationBuilder.DropTable(
            name: "RestartTime");

        migrationBuilder.DropTable(
            name: "ServerVersion");

        migrationBuilder.DropTable(
            name: "StartTime");

        migrationBuilder.DropTable(
            name: "StopTime");

        migrationBuilder.DropTable(
            name: "SimpleTime");
    }
}

搜索了这个问题,发现 sqlite 认没有启用级联,所以我在连接字符串中添加foreign keys=true;。 我也以防万一向这样的每个连接添加PRAGMA foreign_keys = ON

persistenceContext.Database.GetDbConnection().StateChange += (sender,args) =>
{
    if (args.CurrentState == ConnectionState.Open)
    {
        persistenceContext.Database.ExecutesqlRaw("PRAGMA foreign_keys = ON");
    }
};

如何解决此问题并使删除级联?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。