2011-04-10 138 views
1

我在我的數據庫中這兩個表,命名爲供應商和VendorPriceBreaks:刪除多個記錄相關表

Vendors 
----------------- 
VendorID (PK) 
Name 

VendorPriceBreaks 
----------------- 
VendorPriceBreakID (PK) 
VendorID (FK) 
Price 

當我刪除供應商,我想有它刪除相關的所有VendorPriceBreaks以及。我正在使用實體框架。

我想這第一:

public RedirectToRouteResult Delete(int id) 
{ 
    MyEntities entities = new MyEntities(); 

    var vendor = entities.Vendors.FirstOrDefault(v => v.VendorID == id); 
    entities.Vendors.Context.DeleteObject(vendor); 
    entities.Vendors.Context.SaveChanges(); 

    return RedirectToAction("Index"); 
} 

這給了我錯誤消息:DELETE語句衝突與基準約束「FK_VendorPriceBreaks_Vendors」

於是我就加入這行我刪除之前我object:vendor.VendorPriceBreaks.Clear();

但是後來我得到了這個錯誤信息:操作失敗:關係不可能b因爲一個或多個外鍵屬性是不可空的,所以改變了。當對關係進行更改時,相關的外鍵屬性將設置爲空值。如果外鍵不支持空值,則必須定義新的關係,必須爲外鍵屬性指定另一個非空值,或者必須刪除不相關的對象。

這樣做的最佳方式是什麼?

回答

1

您可以「包含」您的子實體。

var vendor = entities.Vendors 
        .Include("VendorPriceBreaks") 
        .FirstOrDefault(v => v.VendorID == id); 

或者,您可以修改.edmx設計器中2個實體之間關係的屬性。

enter image description here

1

如果不啓用級聯刪除數據庫中(這將是在模型中最佳的選擇,我想,看到p.campbell的答案),你必須明確地刪除集合中的項:

public RedirectToRouteResult Delete(int id) 
{ 
    MyEntities entities = new MyEntities(); 

    var vendor = entities.Vendors.FirstOrDefault(v => v.VendorID == id); 
    foreach (var item in vendor.VendorPriceBreaks.ToList()) 
     entities.VendorPriceBreaks.Context.DeleteObject(item); 
    entities.Vendors.Context.DeleteObject(vendor); 
    entities.Vendors.Context.SaveChanges(); 

    return RedirectToAction("Index"); 
} 
1

我想你應該創建一個procedor:

Create proc DeleteRecords 
@VendorID int  
As 
BEGIN TRY 
    BEGIN TRAN 
      DELETE FROM VendorPriceBreaks 
     WHERE VendorID [email protected] 
     DELETE FROM Vendors 
     WHERE VendorID [email protected]   
    COMMIT TRAN 
END TRY 
BEGIN CATCH 
    ROLLBACK TRAN 
END CATCH 

而後就可以此PROC添加到您的entityFramwork的功能。

編碼快樂

+0

刪除的順序應該顛倒。您必須先刪除相關記錄,然後才能刪除父記錄。 – 2011-04-10 22:08:30

+0

uppss :)我知道,很抱歉 – Bilgehan 2011-04-10 22:29:43

1

其他人已經提供了有價值的答案,所以你應該對他們的作爲公認的答案中選擇。

我只是將此作爲答案添加,因爲它太長以至於無法發表評論。通常有四種方法可以實現這一點:

casade刪除,如@ p.campbell所述。重要的是在數據庫中定義ON CASCADE DELETE關係,並在EF設計器中定義關係CascadeHere是選項必須設置在雙方的原因。

@Bilgehan描述的存儲過程。只是在存儲過程的情況下刪除父級之前的子級。您可以直接按ExecuteStoreCommand執行SQL。

Identifying relation - 這是EF中最奇特的architecutre decissions之一。它要求子實體具有從其唯一ID和FK到父級的組合鍵。如果發生這種情況,您可以簡單地致電vendor.VendorPriceBreaks.Clear(),它不僅會刪除關係,還會刪除孩子。缺點是必須從數據庫加載相關對象。

手動刪除相關對象,如@Slauma所述。如果沒有級聯刪除,存儲過程或標識關係,則沒有其他方法,則加載相關對象並逐個刪除它們。