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

时间:2015-05-20 11:17:24

标签: c# entity-framework

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

我有一小段C#可以正常工作。这是:

    var document = _repo.Load<EsignatureDocument>(input.EsignatureDocumentId);

document.Events.Clear();

                document.Fields.Clear();

            _repo.SaveChanges();

当我打电话时,我收到以下错误:

  

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

实体框架类如下:

  [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

1 个答案:

答案 0 :(得分:0)

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 
}