我正在使用 EF Core 中的软删除方法。每个实体都有一个布尔值"活动"。我过滤实体配置层中的所有活动实体。
软删除一对一关系时遇到问题。问题是,尝试添加新关系后出现外键约束冲突。因为数据库对软删除一无所知。它只是检查之前是否使用过外键。
我有一个客户模型,它有一个活动模型。
该方案发生在以下位置;
- 创建客户实例(活动=真(
- 创建营销活动实例(活动 = true( 将"市场活动
- "设置为"客户的市场活动"属性
- 保存更改
- 用于获取上面保存的客户实体的查询
- 访问其广告系列导航属性并设置其活动=假
- 保存更改
- 查询以获取单个客户实体
- 创建新的营销活动实例(活动=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 | 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。