【发布时间】:2022-01-08 22:44:33
【问题描述】:
我使用以下代码使用 EF6 核心创建了表。
问题是, UserA 、 UserB 创建并分配了不同的声明。完全没有问题。分配现有声明时(例如,为 UserB 分配了 UserA 的声明 --> [tying to do] 删除 UserB 的声明并将 UserB 的主题更改为 UserA 的主题)然后我将通过 subjectId 删除 UserB 的声明,这将创建主要UserUserClaims 表中的关键重复问题 bcos SubjectId 和 ClaimId 已经存在
public class User
{
[Key]
public Guid UserId { get; set; }
[MaxLength(200)]
public string Username { get; set; }
[Required]
public Guid Subject { get; set; }
public ICollection<UserClaim> Claims { get; set; } = new List<UserClaim>();
public List<UserClaimRelation> UserClaimRelations { get; set; }
}
public class UserClaim
{
[Key]
public Guid UserClaimId { get; set; }
[MaxLength(250)]
[Required]
public string Type{ get; set; }
[Required]
public Guid Subject { get; set; }
[MaxLength(250)]
[Required]
public string Value { get; set; }
public ICollection<User> Users { get; set; }
public List<UserClaimRelation> UserClaimRelations { get; set; }
}
public class UserClaimRelation
{
public Guid UserClaimId{ get; set; }
public UserClaim Claim { get; set; }
public Guid UserSubject{ get; set; }
public User User { get; set; }
}
public class MyDbContext: DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<UserClaim> UserClaims { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>()
.HasMany(p => p.Claims)
.WithMany(p => p.Users)
.UsingEntity<UserClaimRelation>(
j => j
.HasOne(pt => pt.Claim)
.WithMany(t => t.UserClaimRelations)
.HasPrincipalKey(f => f.UserClaimId),
j => j.HasOne(p => p.User)
.WithMany(t => t.UserClaimRelations)
.HasPrincipalKey( t => t.Subject),
j => j.HasKey( t => new {t.UserClaimId, t.UserSubject})
);
}
我正在尝试按 SubjectId 删除声明
public async Task<bool> DeleteUserClaimsBySubjectAsync(Guid subject)
{
if (subject == Guid.Empty)
{
throw new ArgumentNullException(nameof(subject));
}
var claims = await _context.UserClaims
.Where(x => x.Subject == subject).ToListAsync();
foreach (var claim in claims)
{
_context.UserClaims.Remove(claim);
}
//_context.UserClaims.RemoveRange(claims);
return (await _context.SaveChangesAsync() > 0);
}
在 DeleteUserClaimsBySubjectAsync 中删除声明时,我收到以下错误
SqlException:违反主键约束“PK_UserClaimRelation”。无法在对象“dbo.UserClaimRelation”中插入重复键。重复键值为 (13229d33-99e0-41b3-b18d-4f72127e3971, 8acbbd40-1608-41f2-de59-08d9b58b83d3)。
SQL Profiler 查询
exec sp_executesql N'SET NOCOUNT ON;
INSERT INTO [UserClaimRelation] ([UserClaimId], [UserSubject])
VALUES (@p0, @p1),
(@p2, @p3),
(@p4, @p5),
(@p6, @p7),
(@p8, @p9);
DELETE FROM [UserClaims]
WHERE [UserClaimId] = @p10 AND [ConcurrencyStamp] = @p11;
SELECT @@ROWCOUNT;
DELETE FROM [UserClaims]
WHERE [UserClaimId] = @p12 AND [ConcurrencyStamp] = @p13;
SELECT @@ROWCOUNT;
DELETE FROM [UserClaims]
WHERE [UserClaimId] = @p14 AND [ConcurrencyStamp] = @p15;
SELECT @@ROWCOUNT;
DELETE FROM [UserClaims]
WHERE [UserClaimId] = @p16 AND [ConcurrencyStamp] = @p17;
SELECT @@ROWCOUNT;
DELETE FROM [UserClaims]
WHERE [UserClaimId] = @p18 AND [ConcurrencyStamp] = @p19;
SELECT @@ROWCOUNT;
',N'@p0 uniqueidentifier,@p1 uniqueidentifier,@p2 uniqueidentifier,@p3 uniqueidentifier,@p4 uniqueidentifier,@p5 uniqueidentifier,@p6 uniqueidentifier,@p7 uniqueidentifier,@p8 uniqueidentifier,@p9 uniqueidentifier,@p10 uniqueidentifier,@p11 nvarchar(4000),@p12 uniqueidentifier,@p13 nvarchar(4000),@p14 uniqueidentifier,@p15 nvarchar(4000),@p16 uniqueidentifier,@p17 nvarchar(4000),@p18 uniqueidentifier,@p19 nvarchar(4000)',
@p0='6203BBC3-BD52-4E32-3DDD-08D9B86AB745',@p1='D860EFCA-22D9-47FD-8249-791BA61B07C7',
@p2='80B958C5-FF44-400F-3DDE-08D9B86AB745',@p3='D860EFCA-22D9-47FD-8249-791BA61B07C7',
@p4='A844CB59-5A00-488A-3DDF-08D9B86AB745',@p5='D860EFCA-22D9-47FD-8249-791BA61B07C7',@p6='794AB806-3215-45AF-3DE0-08D9B86AB745',@p7='D860EFCA-22D9-47FD-8249-791BA61B07C7',@p8='80EFF0DF-AE56-419A-3DE1-08D9B86AB745',@p9='D860EFCA-22D9-47FD-8249-791BA61B07C7',@p10='1A48CF6E-E1CD-4042-3DE4-08D9B86AB745',@p11=N'742674d8-3c59-4be4-ac09-38c6804acb66',@p12='258ABD95-6B2A-45CC-3DE6-08D9B86AB745',@p13=N'd206316a-71af-46b7-92e4-bddca669ad87',@p14='4FB1D2E3-18BE-4AFC-3DE3-08D9B86AB745',@p15=N'3eb17fb7-998b-47e1-a97f-3640cbd82b7a',@p16='6C2B9A18-5C8F-4068-3DE5-08D9B86AB745',@p17=N'415b2cc1-b50a-4ec8-872d-13b6342dcd33',@p18='951CEEA6-D057-4588-3DE2-08D9B86AB745',@p19=N'3dfd76dd-d515-4daa-893c-f1ae97aa063a'
【问题讨论】:
-
您是如何填充这些表格的?看起来 EF 想要在您删除的过程中填充连接表 - 您是否以某种方式手动填充它?如果是这样,请尝试使用 EF 分配声明,加载用户并添加声明。然后保存后,尝试删除。
-
在源代码中,您可以看到用于填充关系的 UserClaimRelation 和 MyDbContext 代码。从 UserClaims 中删除时,我不明白为什么要插入 UserClaimRelation,对此有什么想法吗?
-
不要加入
.HasPrincipalKey( t => t.Subject)而是加入 .HasPrincipalKey( t => t.UserClaimId) - 这应该会有所帮助。您仍然可以通过搜索适当的主题来删除。 -
对不起,我没明白你的意思
标签: .net-core entity-framework-core many-to-many cascading-deletes