提问人:József Kiss 提问时间:11/18/2023 最后编辑:marc_sJózsef Kiss 更新时间:11/18/2023 访问量:59
C# &ASP.NET Core:自定义 IdentityUser 的外键冲突
C# & ASP.NET Core : foreign key violation for custom IdentityUser
问:
我想使用具有附加属性的扩展类: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; }
}
我使用两个单独的 s 来区分关注点:DbContext
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
}
}
当我尝试创建一个具有有效 :SpaceShip
userId
[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:保存实体更改时出错。有关详细信息,请参阅内部异常。
Npgsql.PostgresException (0x80004005): 23503:在表“SpaceShips”上插入或更新违反外键约束“FK_SpaceShips_UserEntity_UserId”
详细信息:表“UserEntity”中不存在密钥 (UserId)=(b3a23cba-ad21-4e5a-9b25-8c5e139c67fe)
发生这种情况是因为约束不是指: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
答:
1赞
József Kiss
11/18/2023
#1
仅使用一个数据库上下文解决了该问题:
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);
}
}
但是,我仍然不清楚如何使用两个单独的上下文。
评论
0赞
Ann L.
11/18/2023
既然实体是相关的,并且必须引用这两个实体才能使模型正常工作,为什么还要使用两个单独的上下文?
0赞
József Kiss
11/18/2023
我认为以这种方式管理我的模型会更容易,并且这是推荐的模式。
0赞
Ann L.
11/18/2023
我不知道这是推荐的模式,尽管我敢肯定这是由于我没有读得足够多。它们是否可能意味着上下文的单独实例,而不是单独的上下文类?
评论