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

Sql server 在EF-Core中使用软删除方法时,如何正确实现一对一关系?,sql-server,entity-framework,entity-framework-core,ef-core-3.0,Sql Server,Entity Framework,Entity Framework Core,Ef Core 3.0,我在EF Core中使用软删除方法。每个实体都有一个布尔“活动”。我过滤实体配置层中的所有活动实体 我在软删除一对一关系时遇到问题。问题是,在尝试添加新关系后,我遇到了外键约束冲突。因为数据库对软删除一无所知。它只是检查外键之前是否使用过 我有一个客户模型,它有一个活动模型 这种情况发生在以下情况: 创建客户实例(Active=true) 创建活动实例(Active=true) 将活动设置为客户的活动属性 保存更改 查询以获取上面保存的客户实体 访问其活动导航属性并将其设置为Active=fal

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

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

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

这种情况发生在以下情况:

  • 创建客户实例(Active=true)
  • 创建活动实例(Active=true)
  • 将活动设置为客户的活动属性
  • 保存更改
  • 查询以获取上面保存的客户实体
  • 访问其活动导航属性并将其设置为Active=false
  • 保存更改
  • 查询以获取单个客户实体
  • 创建新的活动实例(Active=true)
  • 将此设置为客户的活动属性
  • 保存更改
  • 步骤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。在我的业务逻辑中,可以手动或在插入具有相同活动ID的新客户时软删除客户


    对于这种情况,我应该采取什么方法?

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

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

    或者,您也可以在表中有一个标识列作为主键,并将客户的活动ID存储为单独的值,该值只是活动的标签

    在重新阅读您的上述要求后,我认为第二种选择最适合您。将使用新标识字段更新从客户到活动的FK。我能看到的最大问题是,按照配置,客户只能有一个活动。如果您需要每个客户有多个活动活动,则需要从客户表中删除活动ID。

    您的表(和表约束)是什么样子的?
    | Id        | Name       | Active | CampaignId
    | --------- |:----------:| ------:| ----------
    | 1         | Mark       | 0      | 1         
    | 2         | James      | 0      | 1         
    | 3         | Henna      | 0      | 1         
    | 4         | Yay        | 1      | 1