c# - 如何正确设置 ApplicationUser 和 FriendRequest 实体以允许级联删除
问题描述
我有传统的ApplicationUser
(IdentityUser),该用户可以向另一个用户发送好友请求ApplicationUser
。我目前有以下通用实体类:
public class ApplicationUser : IdentityUser
{
public virtual List<DeviceToken> DeviceTokens { get; set; } = new List<DeviceToken>();
public string DisplayName { get; set; }
}
public class FriendRequest
{
public int Id { get; set; }
public DateTime DateRequested { get; set; }
public ApplicationUser Requester { get; set; }
public ApplicationUser Receiver { get; set; }
}
我已经运行了数据库更新等,这工作正常。但是,当我进入我的 SQLServer 尝试删除 ApplicationUser 时,它告诉我The DELETE statement conflicted with the REFERENCE constraint "FK_FriendRequest_AspNetUsers_RequesterId"
.
所以我决定实现从 ApplicationUser 到他们所属的朋友请求的级联删除流程。
我已经尝试过微软在此处配置级联删除的资源,但我无法弄清楚如何将其应用于我的案例:
builder.Entity<ApplicationUser>()
.HasMany(e => e.FriendRequests)//No such property, no idea how to address
.OnDelete(DeleteBehavior.ClientCascade);
如何设置此级联删除方案?
另外,如何向 ApplicationUser 添加一个属性,该属性引用它们所属的所有 FriendRequest,并确保 EFCore 知道我指的是现有的 FriendRequest 实体/表?
更新
遵循向 ApplicationUser 添加虚拟属性的建议方法,这将是前进的方向:
public class ApplicationUser : IdentityUser
{
public virtual List<DeviceToken> DeviceTokens { get; set; } = new List<DeviceToken>();
public string DisplayName { get; set; }
public ICollection<FriendRequest> FriendRequests { get; }
}
builder.Entity<ApplicationUser>()
.HasMany(u => u.FriendRequests)
.WithOne(u => u.Requester)
.OnDelete(DeleteBehavior.ClientCascade); //not sure about this
builder.Entity<ApplicationUser>()
.HasMany(u => u.FriendRequests)
.WithOne(u => u.Requester)
.OnDelete(DeleteBehavior.ClientCascade); //not sure about this
解决方案
您的 ApplicationUser 需要 2 个虚拟 ICollections。
public class ApplicationUser
{
public int Id { get; set; }
public string DisplayName { get; set; }
public virtual ICollection<FriendRequest> FriendRequestsAsRequestor { get; set; }
public virtual ICollection<FriendRequest> FriendRequestsAsReceiver { get; set; }
}
public class FriendRequest
{
public int Id { get; set; }
public DateTime DateRequested { get; set; }
public int RequestorId { get; set; }
public ApplicationUser Requestor { get; set; }
public int ReceiverId { get; set; }
public ApplicationUser Receiver { get; set; }
}
public class ApplicationUserConfig : IEntityTypeConfiguration<ApplicationUser>
{
public void Configure(EntityTypeBuilder<ApplicationUser> builder)
{
builder.HasMany(au => au.FriendRequestsAsRequestor)
.WithOne(fr => fr.Requestor)
.HasForeignKey(fr => fr.RequestorId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasMany(au => au.FriendRequestsAsReceiver)
.WithOne(fr => fr.Receiver)
.HasForeignKey(fr => fr.ReceiverId)
.OnDelete(DeleteBehavior.Cascade);
}
}
利用:
void AddFriendRequest(int requestorId, int receiverId)
{
var ctxt = new DbContext();
FriendRequest fr = new FriendRequest
{
RequestorId = requestorId;
ReceiverId = receiverId;
DateRequested = DateTime.Now;
}
ctxt.FriendRequests.Add(fr);
ctxt.SaveChanges();
}
List<FriendRequest> GetFriendRequests()
{
var ctxt = new DbContext();
return ctxt.FriendRequests
.Include(fr => fr.Requestor)
.Include(fr => fr.Receiver)
.ToList();
}
ApplicationUser GetUserWithFriendRequests(int id)
{
var ctxt = new DbContext();
return ctxt.ApplicationUser
.Include(au => au.FriendRequestsAsRequestor)
.Include(au => au.FriendRequestsAsReceiver)
.SingleOrDefault(au => au.Id == id);
}
推荐阅读
- java - java 8 - Arrays.stream().filter 过滤掉空字符串并转换为数组
- mysql - mysql:使用group by时未分组的项目崩溃
- java - 位图压缩质量差
- wordpress - 暂存站点的 Wordpress 仪表板警报问题
- ios - common Navigation Button Action 另一类
- ios - 如何解决此警告:在错误包含的文件中?
- c# - 使用 Automapper 简洁地插入/更新/删除可枚举的子实体
- python - 在 pandas 和 matplotlib 中,为什么不直接在数据帧上调用 plt?
- r - 如何获得从 R 中的回归分析生成的四个图?
- field - 在 Odoo 的表单视图中设置为当前日期时间的字段的默认值