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

时间:2019-11-20 23:01:02

标签: sql-server entity-framework entity-framework-core ef-core-3.0

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

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

我有一个客户模型,该模型具有一个广告系列模型。

该情况发生在下面;

  1. 创建客户实例(Active = true)
  2. 创建广告系列实例(Active = true)
  3. 将广告系列设置为客户的广告系列属性
  4. 保存更改
  5. 查询以获取上方保存的客户实体
  6. 访问其Campaign导航属性并设置其Active = false
  7. 保存更改
  8. 查询以获取单个Customer实体
  9. 创建新的Campaign实例(Active = true)
  10. 将此设置为“客户的广告系列”属性
  11. 保存更改

步骤11抛出异常,例如“ INSERT语句与FOREIGN KEY约束冲突”

模型:

 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的新客户软删除客户。

在这种情况下我应该采取什么方法?

1 个答案:

答案 0 :(得分:0)

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

假设以上所述,我为您的Campaign表推荐的主键是CustomerID和CampaignID的组合。该值将始终具有唯一值(只要您确保不为给定客户重复使用广告系列ID。)

或者,您也可以在表上使用“身份”列作为主键,并将客户的广告系列ID存储为单独的值,该值只是广告系列的标签。

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