删除定义了 `DeleteBehavior.ClientCascade` 的实体时出现异常

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

我在删除具有指向正在删除的帐户实体的外键的表时遇到异常

InnerException = {"SQLite Error 19: 'FOREIGN KEY constraint failed'."}
。我已经标记了抛出异常的代码行(在
DeleteAllUserAccounts
方法中)。我已经在
DeleteBehavior.ClientCascade
的配置部分正确定义了
DataContext
(见下文)。为什么我仍然遇到异常?

 public class DataContext : IdentityDbContext<Account>
{
    private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    public DbSet<SystemInfo> SystemInformation { get; set; }

    public DbSet<Account> Accounts { get; set; }
    public DbSet<Schedule> Schedules { get; set; }

    public DbSet<Function> UserFunctions { get; set; }
    public DbSet<SchedulePoolElement> SchedulePoolElements { get; set; }

    public DbSet<RefreshToken> RefreshTokens { get; set; }

    private readonly IConfiguration Configuration;


    
    public DataContext(IConfiguration configuration, DbContextOptions options) : base(options)
    {
        Configuration = configuration;
    }

    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        // connect to sqlite database
        options.UseSqlite(Configuration.GetConnectionString("WebApiDatabase"));
    }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        //modelBuilder.Entity<Account>().HasMany(e => e.RefreshTokens).WithOne(e => e.Account).IsRequired();
        modelBuilder.Entity<SystemInfo>().HasData(
        new SystemInfo
        {
            Id = 1,
            NoOfEmailsSentDayily = 1,
            autoEmail = false
        });
        modelBuilder.Entity<Account>()
            .HasMany<Schedule>(a => a.Schedules)
            .WithOne()
            .OnDelete(DeleteBehavior.ClientCascade);
        modelBuilder.Entity<Account>()
            .HasMany<Function>(a => a.UserFunctions)
            .WithOne()
            .OnDelete(DeleteBehavior.ClientCascade);
        modelBuilder.Entity<Account>()
            .HasMany<RefreshToken>(a => a.RefreshTokens)
            .WithOne(r=> r.Account)
            .OnDelete(DeleteBehavior.ClientCascade);
    }
}


public IEnumerable<AccountResponse> DeleteAllUserAccounts()
        {
            log.Info("DeleteAllUserAccounts before locking");
            semaphoreObject.Wait();

            using (IDbContextTransaction transaction = _context.Database.BeginTransaction())
            {
                try
                {
                    var foundAccounts = _context.Accounts.Where(x => x.Role != Role.Admin).ToArray().ToList();
                    int count = foundAccounts.Count();
                    _context.Accounts.RemoveRange(foundAccounts);

                    _context.SaveChanges(); <----- Exception(InnerException = {"SQLite Error 19: 'FOREIGN KEY constraint failed'."})
                    transaction.Commit();

                    var accounts = _context.Accounts;
                    return _mapper.Map<IList<AccountResponse>>(accounts);
                }
                catch (Exception ex)
                {
                    transaction.Rollback();
                    Console.WriteLine(Thread.CurrentThread.Name + "Error occurred.");
                    log.Error(Thread.CurrentThread.Name + "Error occurred in Delete:", ex);
                    throw;
                }
                finally
                {
                    semaphoreObject.Release();
                    log.Info("Delete after locking");
                }
            }
        }

public class Account : IdentityUser
    { 
        ...

        public List<Schedule> Schedules { get; set; }
        public List<Function> UserFunctions { get; set; }
        public List<RefreshToken> RefreshTokens { get; set; }

        public bool OwnsToken(string token) 
        {
            return this.RefreshTokens?.Find(x => x.Token == token) != null;
        }
    }
c# sqlite cascading-deletes
1个回答
0
投票

可能需要启用外键级联删除,请在此处查看答案: 在 sqlite3 中删除级联 此处用于从 C# 运行该查询: 如何在SQLite中默认启用外键级联删除?

如果没有此设置,您也可以提前手动删除相关记录。

© www.soinside.com 2019 - 2024. All rights reserved.