我有一个使用SQLite数据库的C#应用程序,它生成了一个异常:
Microsoft.EntityFrameworkCore.DbUpdateException:'保存实体更改时出错。有关详细信息,请参见内部异常。'
内部异常:SqliteException:SQLite错误19:'NOT NULL约束失败:RefreshTokens.
我通过添加以下内容修复了这个bug(在从DbContext
派生的类中):
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; }
}
}
型
1条答案
按热度按时间nimxete21#
您在“Account”和“RefreshTokens”之间创建了一个关系,并且您的外键“AccountId”为null,但您对“AccountId”的配置为“IsRequired”
这样试试
字符串