如何在EF Core中使用软删除方法时正确实现一对一关系?



我正在使用 EF Core 中的软删除方法。每个实体都有一个布尔值"活动"。我过滤实体配置层中的所有活动实体。

软删除一对一关系时遇到问题。问题是,尝试添加新关系后出现外键约束冲突。因为数据库对软删除一无所知。它只是检查之前是否使用过外键。

我有一个客户模型,它有一个活动模型。

该方案发生在以下位置;

  1. 创建客户实例(活动=真(
  2. 创建营销活动实例(活动 = true(
  3. 将"市场活动
  4. "设置为"客户的市场活动"属性
  5. 保存更改
  6. 用于获取上面保存的客户实体的查询
  7. 访问其广告系列导航属性并设置其活动=假
  8. 保存更改
  9. 查询以获取单个客户实体
  10. 创建新的营销活动实例(活动=true(
  11. 将其设置为"客户的市场活动"属性
  12. 保存更改

步骤 11 抛出异常,例如"INSERT 语句与外键约束冲突">

模型:

 public class Customer{
    public long Id { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
    public Campaign Campaign {get; set;}
    public long CampaignId { get; set; }
 }
 public class Campaign{
    public long Id { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
    public Customer Customer {get; set;}
 }

实体配置(根据 IEntityTypeConfiguration( 分隔(:

客户;

modelBuilder.HasKey(a => a.Id);
modelBuilder.HasQueryFilter(a => a.Active);

运动;

modelBuilder.HasKey(a => a.Id);
modelBuilder.HasOne(c => c.Customer)
    .WithOne(c => c.Campaign)
    .HasForeignKey<Customer>(c => c.CampaignId)
    .OnDelete(DeleteBehavior.Restrict);
modelBuilder.HasQueryFilter(a => a.Active);

客户表中说明它;

| Id        | Name       | Active | CampaignId
| --------- |:----------:| ------:| ----------
| 1         | Mark       | 0      | 1         
| 2         | James      | 0      | 1         
| 3         | Henna      | 0      | 1         
| 4         | Yay        | 1      | 1          

我真正需要的是这种一对一的关系。我不希望 2 个活跃客户具有相同的 CampaignId。在我的业务逻辑中,可以手动软删除客户,也可以在插入具有相同 CampaignId 的新客户期间软删除客户。

对于这种情况,我应该遵循什么方法?

在这种情况下,外键不是正确的解决方案。尽管您显然希望能够将其 Campaign Id 值编号为广告系列 1、2、3 等......这些属性应该是"广告系列名称"属性或复合主键的一部分,而不是任何形式的标识属性。

假设上述情况,我为您的广告系列表建议的主键是 CustomerID 和 Campaign ID 的组合。 这将始终具有唯一值(只要您确保不为给定客户重复使用市场活动 ID。

或者,您也可以将表上的 Identity 列作为主键,并将客户的市场活动 ID 存储为单独的值,该值只是活动的标签。

重新阅读您上面的请求后,我认为第二种选择最适合您。从客户到市场的 FK 将使用新的标识字段进行更新。我能看到的最大问题是,按照配置,客户只能有一个有效的广告系列。如果您需要为每个客户设置多个有效广告系列,则需要从客户表中删除 CampaignID。

最新更新