簡體   English   中英

嘗試級聯刪除時出錯

[英]Error while trying to cascade-delete

嘗試從數據庫中刪除項目時,出現以下錯誤消息:

操作失敗:由於一個或多個外鍵屬性不可為空,因此無法更改該關系。 對關系進行更改時,相關的外鍵屬性將設置為空值。 如果外鍵不支持空值,則必須定義新的關系,必須為外鍵屬性分配另一個非空值,或者必須刪除不相關的對象。

我已經閱讀了許多有關此問題的主題,但是似乎沒有一個對您有幫助的(或者也許我不太了解它們)。

我的模型是:

public class ARDOperation
    {    
        [Key]                
        public int ARD { get; set; }

        [Required]               
        public virtual ICollection<Act> Actions { get; set; }

        public ARDOperation()
        {
            this.Actions = new List<Act>();
        }

    }
public class Act
{                      
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ARDID { get; set; }
    public int ARDOperationId { get; set; }

    [ForeignKey("ARDOperationId")]        
    public virtual ARDOperation ARDOperation { get; set; }

    public string Data { get; set; }

    [EnumDataType(typeof(ARDState))]
    public ARDState State { get; set; }
}

我還定義了一個流暢的API:

    public class ARDOperationDBContext : DbContext
    {            
        public DbSet<ARDOperation> ARDOperation { get; set; }
        //public DbSet<Act> Act { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Act>()
            .HasRequired(t => t.ARDOperation)
            .WithMany(t => t.Actions)
            .HasForeignKey(d => d.ARDOperationId)
            .WillCascadeOnDelete(true);                

            //modelBuilder.Entity<ARDOperation>()

        }

控制器中的方法:

        internal void RemoveAction(int ARDID)
        {
        var op = ARDOperationDB.ARDOperation.Find(ARDID);
        if (op != null)
        {
            //will not remove the "idle" action
            if (op.Actions.Count > 1)                                
            {
                Act act = op.Actions.ElementAt(1);                                        
                op.Actions.Remove(act);                    
                //ARDOperationDB.Entry(op).State = EntityState.Modified;
                ARDOperationDB.SaveChanges();                                                           
            }                
        }
    }

我嘗試使用代碼優先方法將“ ARDOperationId”屬性定義為可為空(int?),並且我沒有通過這種方式得到任何錯誤,但是子級的數據仍然保留在DB中。

我認為我缺少與訪問該法案模型有關的內容。

謝謝您的幫助,尤瓦爾。

看看EF專家關於remove方法的[this answer] [1]。

EntityCollection.Remove(childEntity)將parent和childEntity之間的關系標記為Deleted。 如果將childEntity本身從數據庫中刪除,則調用SaveChanges時究竟發生了什么,取決於兩者之間的關系類型:

如果該關系是可選的,即從數據庫中的子項到父項引用的外鍵允許使用NULL值,則該外鍵將設置為null,並且如果您調用SaveChanges,則childEntity的此NULL值將被寫入數據庫(也就是說,兩者之間的關系已刪除)。 使用SQL UPDATE語句會發生這種情況。 沒有發生DELETE語句。

如果需要該關系(FK不允許使用NULL值)並且該關系沒有標識(這意味着外鍵不屬於子級(復合)主鍵的一部分),則必須將子級添加到另一個父級中否則您必須顯式刪除該子項(然后使用DeleteObject)。 如果您不執行任何這些操作,則將違反引用約束,並且在調用SaveChanges時EF將引發異常-臭名昭著的“由於一個或多個外鍵屬性是不可空的,因此無法更改關系”異常或類似。

如果該關系是可識別的(那么這是必需的,因為主鍵的任何部分不能為NULL),EF也會將childEntity標記為Deleted。 如果調用SaveChanges,則會將SQL DELETE語句發送到數據庫。 如果沒有違反數據庫中的其他引用約束,則將刪除該實體,否則將引發異常。

[1]: 實體框架.Remove()與.DeleteObject()

所以我讀了很多關於這個主題的文章。 克里斯在這里的反應非常好,對我的理解很有幫助: 鏈接

但是真正幫助我的是這里的小代碼示例: Solution

“ [Key,ForeignKey(“ Order”),Column(Order = 1)]“部分確實起到了作用。

非常感謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM