我在删除具有指向正在删除的帐户实体的外键的表时遇到异常
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;
}
}
可能需要启用外键级联删除,请在此处查看答案: 在 sqlite3 中删除级联 此处用于从 C# 运行该查询: 如何在SQLite中默认启用外键级联删除?
如果没有此设置,您也可以提前手动删除相关记录。