在这种情况下,如何对实体执行级联删除?

本文关键字:执行 级联 删除 实体 这种情况下 | 更新日期: 2023-09-27 17:49:51

如何从EsignatureDocument中删除字段和事件(定义如下)而不会导致错误?我怀疑我可以写一些模型构建代码,在DbContext的应用程序启动时执行,使用EntityTypeConfiguration…以下示例的构建器代码是什么?

我有一小段c#可以工作。

    var document = _repo.Load<EsignatureDocument>(input.EsignatureDocumentId);
document.Events.Clear();
                document.Fields.Clear();
            _repo.SaveChanges();
当我调用它时,我收到以下错误:

无法更改关系,因为一个或多个外键属性不可为空。进行更改时关系时,相关的外键属性设置为空值。如果外键不支持空值,则建立新的关系必须定义,外键属性必须分配另一个非空值,否则必须删除不相关的对象。

实体框架类如下:

  [Table("EsignatureDocument", Schema = "dbo")]
    public class EsignatureDocument 
    {
        public EsignatureDocument()
        {
            Events = new HashSet<EsignatureDocumentEvent>();
        }
public Guid Id { get; set; }
        public DateTime CreatedDate { get; set; }
        [MaxLength(10)]
        public string DocumentReference { get; set; }
        [MaxLength(100)]
        public string CreatedBy { get; set; }
        [MaxLength(300)]
        public string EnvelopeTitle { get; set; }
        [MaxLength(500)]
        public string Path { get; set; }
        [MaxLength(500)]
        public string SignedPath { get; set; }
        [MaxLength(200)]
        public string SignedUrl { get; set; }
        [MaxLength(200)]
        public string SignableUrl { get; set; }
        public DateTime? SignedDate { get; set; }
        [MaxLength(32)]
        public string EnvelopeFingerprint { get; set; }
        public bool SentByEmail { get; set; }
        public bool SentBySms { get; set; }
        [MaxLength(200)]
        public string EmailAddress { get; set; }
        [MaxLength(20)]
        public string MobileNumber { get; set; }
        [MaxLength(100)]
        public string LetterReference { get; set; }
        public virtual HashSet<EsignatureDocumentEvent> Events { get; set; }
        public virtual HashSet<EsignatureDocumentField> Fields { get; set; }
        [NotMapped]
        public bool IsSigned
        {
            get { return !string.IsNullOrWhiteSpace(SignedPath); }
        }
        [NotMapped]
        public EsignatureDocumentEvent LatestEvent 
        {
            get { return Events.OrderByDescending(x => x.CreatedDate).FirstOrDefault(); } 
        }
    }
[Table("EsignatureDocumentEvent", Schema = "dbo")]
    public class EsignatureDocumentEvent : EntityBase
    {
        public Guid EsignatureDocumentId { get; set; }
        public SignableAction Action { get; set; }
        [MaxLength(50)]
        public string ActionName { get; set; }
        [NotMapped]
        public string ActionDisplayName {
            get
            {
                return char.ToUpper(ActionName[0]) + ActionName.Substring(1).ToLower().Replace("_envelope", string.Empty);
            } 
        }
        public string FieldsJson { get; set; }
        [MaxLength(1000)]
        public string DocumentPdf { get; set; }
        public DateTime CreatedDate { get; set; }
    }
[Table("EsignatureDocumentField", Schema = "dbo")]
    public class EsignatureDocumentField  
    {
        [Key]
        public int Field_Id { get; set; }
        public string Field_Value { get; set; }
        public string Field_Name { get; set; }
        public string Field_Type { get; set; }
        public virtual EsignatureDocument EsignatureDocument { get; set; }
        public Guid EsignatureDocumentId { get; set; }
    }

子表脚本如下:

CREATE TABLE [dbo].[EsignatureDocumentEvent](
    [Id] [uniqueidentifier] NOT NULL,
    [EsignatureDocumentId] [uniqueidentifier] NOT NULL,
    [Action] [int] NOT NULL,
    [ActionName] [varchar](50) NOT NULL,
    [FieldsJson] [varchar](max) NULL,
    [DocumentPdf] [varchar](1000) NULL,
    [CreatedDate] [datetime] NOT NULL,
 CONSTRAINT [PK_EsignatureDocumentEvent] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO

  ALTER TABLE [dbo].[EsignatureDocumentEvent]  WITH CHECK ADD  CONSTRAINT [FK_EsignatureDocumentEvent_EsignatureDocument] FOREIGN KEY([EsignatureDocumentId])
    REFERENCES [dbo].[EsignatureDocument] ([Id])
    GO
    ALTER TABLE [dbo].[EsignatureDocumentEvent] CHECK CONSTRAINT [FK_EsignatureDocumentEvent_EsignatureDocument]
    GO
CREATE TABLE [dbo].[EsignatureDocumentField](
    [Field_Id] [int] NOT NULL,
    [Field_Name] [varchar](100) NOT NULL,
    [Field_Value] [varchar](1000) NOT NULL,
    [Field_Type] [varchar](100) NOT NULL,
    [EsignatureDocumentId] [uniqueidentifier] NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [Field_Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[EsignatureDocumentField]  WITH CHECK ADD  CONSTRAINT [FK_EsignatureDocumentField_EsignatureDocument] FOREIGN KEY([EsignatureDocumentId])
REFERENCES [dbo].[EsignatureDocument] ([Id])
GO
ALTER TABLE [dbo].[EsignatureDocumentField] CHECK CONSTRAINT [FK_EsignatureDocumentField_EsignatureDocument]
GO

在这种情况下,如何对实体执行级联删除?

Clear()删除对父实体的引用,而不是子实体本身。

问题是,当您调用document.Fields.Clear()时,它将使Field实体上的EsignatureDocumentId列无效。这是不允许的,因为EsignatureDocumentId是不可空的,所以你不能有一个没有父文档的字段。要么将列标记为可空,要么使用:

foreach(var f in document.Field) 
{
    Context.DeleteObject(f); //or fieldRepo.Delete(f) or something that fits for 
}