我想使用带有附加属性的扩展 IdentityUser 类,
namespace SpaceShip.Model;
using Microsoft.AspNetCore.Identity;
public class UserEntity : IdentityUser
{
// Additional properties
}
在我的模型类中使用它的 Id 作为外键
public class SpaceShip
{
public int Id { get; set; }
public string Name { get; set; }
public string UserId { get; set; }
// Navigation property
public UserEntity User { get; set; }
}
我使用两个单独的数据库上下文来分隔关注点:
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public DbSet<SpaceShipModel> SpaceShips { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Configure the relationship between SpaceShip and AspNetUsers (UserEntity)
builder.Entity<SpaceShipModel>()
.HasOne<UserEntity>(s => s.User)
.WithMany()
.HasForeignKey(s => s.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
}
}
public class UserContext : IdentityDbContext<UserEntity>
{
public UserContext(DbContextOptions<UserContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Additional configuration
}
}
当我尝试使用有效的 userId 创建新的 SpaceShip 时:
[ApiController]
[Route("[controller]")]
public class SpaceShipController : ControllerBase
{
private readonly SpaceShipService _spaceShipService;
public SpaceShipController(SpaceShipService spaceShipService)
{
_spaceShipService = spaceShipService;
}
[HttpPost]
public async Task<IActionResult> Create(string name, string userId)
{
await _spaceShipService.CreateSpaceShipAsync(name, userId);
return Ok();
}
}
我收到错误:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
---> Npgsql.PostgresException (0x80004005): 23503: insert or update on table "SpaceShips" violates foreign key constraint "FK_SpaceShips_UserEntity_UserId"
DETAIL: Key (UserId)=(b3a23cba-ad21-4e5a-9b25-8c5e139c67fe) is not present in table "UserEntity"
发生这种情况是因为约束:FK_SpaceShips_UserEntity_UserId 不引用“AspNetUsers”:
-- Constraint: FK_SpaceShips_UserEntity_UserId
-- ALTER TABLE IF EXISTS public."SpaceShips" DROP CONSTRAINT IF EXISTS "FK_SpaceShips_UserEntity_UserId";
ALTER TABLE IF EXISTS public."SpaceShips"
ADD CONSTRAINT "FK_SpaceShips_UserEntity_UserId" FOREIGN KEY ("UserId")
REFERENCES public."UserEntity" ("Id") MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE;
可以通过修改FK_SpaceShips_UserEntity_UserId引用“AspNetUsers”来暂时解决问题:
-- Constraint: FK_SpaceShips_UserEntity_UserId
-- ALTER TABLE IF EXISTS public."SpaceShips" DROP CONSTRAINT IF EXISTS "FK_SpaceShips_UserEntity_UserId";
ALTER TABLE IF EXISTS public."SpaceShips"
ADD CONSTRAINT "FK_SpaceShips_UserEntity_UserId" FOREIGN KEY ("UserId")
REFERENCES public."AspNetUsers" ("Id") MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE;
但它应该由实体框架配置,后续迁移可能会覆盖它。我不明白为什么外键约束默认不引用“AspNetUsers”。
仅使用一个数据库上下文解决了问题:
public class AppDbContext : IdentityDbContext<UserEntity>
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
}
public DbSet<SpaceShipModel> SpaceShips { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Map UserEntity to AspNetUsers table
builder.Entity<UserEntity>().ToTable("AspNetUsers");
// Configure the relationship between SpaceShip and UserEntity (AspNetUsers)
builder.Entity<SpaceShipModel>()
.HasOne<UserEntity>(s => s.User)
.WithMany()
.HasForeignKey(s => s.UserId)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
}
}
但是我仍然不清楚如何使用两个单独的上下文。