注释EF Core关联配置后未触发预期Bug,是否为缓存问题?
问题:无法重现SQLite的NOT NULL约束异常
我有一个使用SQLite数据库的C#应用,曾触发以下异常:
Microsoft.EntityFrameworkCore.DbUpdateException: '保存实体更改时发生错误。请查看内部异常了解详细信息。'
内部异常:SqliteException: SQLite Error 19: 'NOT NULL constraint failed: RefreshTokens.AccountId'。
我通过在DbContext派生类中添加以下代码修复了该Bug:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Account>() .HasMany(e => e.RefreshTokens) .WithOne(e => e.Account) .IsRequired(); }
我想要复现该Bug,因此注释了这段代码:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // modelBuilder.Entity<Account>() // .HasMany(e => e.RefreshTokens) // .WithOne(e => e.Account) // .IsRequired(); }
但代码仍正常运行,似乎存在某种缓存问题。我需要做些什么才能让该Bug重现?
相关代码
数据库更新代码(getRefreshToken方法及相关)
private (RefreshToken, Account) getRefreshToken(string token) { var account = _context.Accounts .Include(x => x.RefreshTokens) .SingleOrDefault(u => u.RefreshTokens.Any(t => t.Token == token)); if (account == null) { Console.WriteLine("Exception thrown"); throw new AppException("Invalid token"); } var refreshToken = account.RefreshTokens .Single(x => x.Token == token); if (!refreshToken.IsActive) throw new AppException("Invalid token"); return (refreshToken, account); } public AuthenticateResponse RefreshToken(string token, string ipAddress) { log.Info("RefreshToken before locking"); Monitor.Enter(lockObject); using (IDbContextTransaction transaction = _context.Database.BeginTransaction()) { try { var (refreshToken, account) = getRefreshToken(token); _context.Update(account); _context.SaveChanges(); transaction.Commit(); return response; } catch (Exception ex) { transaction.Rollback(); Console.WriteLine(Thread.CurrentThread.Name + "Error occurred."); log.Error("RefreshToken:" + ex.Message); throw ex; } finally { Monitor.Exit(lockObject); log.Info("RefreshToken after locking"); } } } namespace WebApi.Helpers { public class DataContext : DbContext { 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) { Configuration = configuration; } protected override void OnConfiguring(DbContextOptionsBuilder options) { // connect to sqlite database options.UseSqlite(Configuration.GetConnectionString("WebApiDatabase")); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Account>().HasMany(e => e.RefreshTokens).WithOne(e => e.Account).IsRequired(); } } }
Account类
using System; using System.Collections.Generic; namespace WebApi.Entities { public class Account { public int Id { get; set; } public string Title { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public List<RefreshToken> RefreshTokens { get; set; } } }
RefreshToken类
using Microsoft.EntityFrameworkCore; using System; using System.ComponentModel.DataAnnotations; namespace WebApi.Entities { [Owned] public class RefreshToken { [Key] public int Id { get; set; } public Account Account { get; set; } public string Token { get; set; } } }
内容的提问来源于stack exchange,提问作者janci
相关产品推荐
相关产品推荐

