ForeignKey SetNull OnDelete



我想知道是否可以使用复合外键,将此外键的一列设置为null时,当我删除相关行。

的确,第二列(我不想为null(用于我不想停用的其他外国钥匙。

精度:我使用实体框架核心(最后版本(。

据我所知,

这是不可能的,因为您的外键值会引用不存在的记录。但是,您可能会使用一些解决方法:

另一列

您可能会创建具有相同值的另一列,而您的旧列只会引用您打算进行删除的表,其他表的外键将链接到具有相同值的新列

不定为此表的外键

您可以避免在表格上删除记录的表格,因此没有任何限制会影响您。

关闭外键检查

这将"解决"您的问题,但应尽可能避免。

虚拟删除

在目标表中您可以创建一个已删除的标志并将其设置为true而不是实际删除。

感谢您的回答。

我同意您所说的一切,除了一件事:

据我所知,这是不可能的,因为您的外国钥匙值然后将引用不存在的记录。

其中一列之一是无效的事实(我想设置为null(,允许我制作以下fk {parendId:null,null,tenantid:4}参考文献无行。如果我设置了parentID,则FK现在引用一行。

就我而言,我只想删除父,只有parentid设置为null,而不是用于其他FK的tenantid,也将其设置为PK。但是我得出的结论是,您不可能...

最后,我覆盖了savechanges方法来探索孩子并将FK的所有列部分设置为null(the the the tenantid(。

这是允许在一个实体导航属性上迭代的代码:

foreach (var navigationEntry in entry.Navigations
                            .Where(n => !n.Metadata.IsDependentToPrincipal()))
{
    if (navigationEntry is CollectionEntry collectionEntry)
    {
        // FK uses DeleteBehavior.ClientSetNull -> let's set it to NULL
        if (((Microsoft.EntityFrameworkCore.Metadata.Internal.Navigation)((MemberEntry)navigationEntry).Metadata).Builder.Metadata.ForeignKey.DeleteBehavior == DeleteBehavior.ClientSetNull)
        {
            // getting all fields composing the FK (except TenantId)
            List<string> fieldsToSetToNull = ((Microsoft.EntityFrameworkCore.Metadata.Internal.Navigation)((MemberEntry)navigationEntry).Metadata).Builder.Metadata.ForeignKey.Properties.Where(x => x.Name != nameof(IMustHaveTenant.TenantId)).Select(x => x.Name).ToList();
            List<object> dependentEntitiesList = new List<object>((IEnumerable<object>)collectionEntry.CurrentValue);
            for (var i = dependentEntitiesList.Count - 1; i >= 0; i--)
            {
                // setting all fields to NULL
                foreach (string fi in fieldsToSetToNull)
                {
                    var childEntry = this.Entry(dependentEntitiesList[i]);
                    childEntry.CurrentValues[fi] = null;
                }
            }
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新