2011-04-14 97 views
1

使用實體框架,我的代碼使用LINQ獲取需要從數據庫中刪除的對象的集合。這個集合有時候相當大,取決於具體情況 - 30或40個對象。實體框架 - 如何找出導致參照完整性錯誤的原因?

我繼續嘗試從它們的相關對象中去耦這些對象,以便我可以刪除它們,然後對每個對象調用context.DeleteObject(),最後調用context.SaveChanges()。

大多數情況下,這很好地工作,特別是當要刪除的對象集合非常小時。然而,當其大,該代碼有時會拋出和錯誤各地參照完整性,具體如下:

The DELETE statement conflicted with the REFERENCE constraint 
\"FK_ServiceFeatureSchemaFragmentSchemaFragment_SchemaFragment\". 
The conflict occurred in database \"MyDataBase\", 
table \"dbo.ServiceFeatureSchemaFragmentSchemaFragment\".\r\n 
The statement has been terminated. 

如此看來,有時候我的對象有我沒有找到和解夫婦在刪除前附加約束。

我正在努力的是,因爲我正在處理一個相對較大的集合,我無法確定哪一個(s)導致這種情況發生。我正在尋找關於如何通過以某種方式識別問題對象來推進的建議,例如,是否有方法可以預先確定集合中的對象是否會在您之前拋出這些類型的錯誤刪除它們?還是另一種方法?

感謝收到的建議。

回答

0

在SQL Server中編寫存儲過程,您可以在其中看到FK/PK關係的影響,而無需額外的EF映射層來混淆事物。此示例使用用戶的主概要表中的基於整數的ezUserID或ASP.NET成員資格GUID來開始刪除。

你可以簡單地使用級聯刪除當你定義你的人際關係......

SET ANSI_NULLS ON 
SET QUOTED_IDENTIFIER ON 
GO 


CREATE PROC [dbo].[ezUser_Delete] 
    @ezUserID int = NULL, 
    @UserName nvarchar(128) = NULL 
AS 
BEGIN 
    SET NOCOUNT ON 

    DECLARE @UserID uniqueidentifier; 

    --DECLARE @TranName VARCHAR(20); --Generally shouldn't use named transactions in stored procedures 
    --SELECT @TranName = 'MyTransaction'; 
    SET XACT_ABORT ON 

    IF @ezUserID IS NULL AND @UserName IS NULL RETURN 0 

BEGIN TRY 
    BEGIN TRANSACTION; 

      IF ISNULL(@ezUserID, 0) > 0 

       BEGIN 
        SELECT @UserID = UserID FROM ezUsers WHERE ezUserID = @ezUserID 
        SELECT @UserName = UserName FROM aspnet_Users WHERE UserID = @UserID 
        IF (@UserName IS NULL) 
         BEGIN 
          ROLLBACK TRANSACTION; 
          RETURN -1 
         END 
       END 

      ELSE IF (LEN(ISNULL(@UserName,'')) > 0) 

       BEGIN 
        SELECT @UserID = UserID FROM aspnet_Users WHERE UserName = @UserName 
        SELECT @ezUserID = ezUserID FROM ezUsers WHERE UserID = @UserID 
        IF (@ezUserID IS NULL) 
         BEGIN 
          ROLLBACK TRANSACTION; 
          RETURN -1 
         END 
       END 

      ELSE 
       RETURN -1 

      SELECT 'DELETE' AS [Command] 
       , U.UserID 
       , U.UserName 
       , RoleName 
       , M.Email 
       , EU.ezUserID 
       , EU.FirstName, EU.LastName 
       , CallSign 
       , Gender 
       , UIR.RoleID 

      FROM dbo.aspnet_Users U 
        LEFT OUTER JOIN dbo.aspnet_Membership M ON U.UserID = M.UserID 

        LEFT OUTER JOIN dbo.ezUsers EU ON U.UserID = EU.UserID  

        LEFT OUTER JOIN dbo.aspnet_UsersInRoles UIR ON U.UserID = UIR.UserID 
        LEFT OUTER JOIN dbo.aspnet_Roles R ON UIR.RoleID = R.RoleID  
      WHERE U.UserID = @UserID 

      IF @UserID IS NULL 
       RETURN -1 

      DELETE FROM dbo.ezUsersDating WHERE ezUserID = @ezUserID 
      DELETE FROM dbo.ezUsersPhysicalIdentity WHERE ezUserID = @ezUserID 

      DELETE FROM dbo.ezMessages WHERE AuthorID = @ezUserID 

      DELETE FROM dbo.ezTheUsual WHERE ezUserID = @ezUserID 
      DELETE FROM dbo.ezRentals WHERE ezUserID = @ezUserID 

      DELETE FROM dbo.ezUsersSharedActivities WHERE ezUserID = @ezUserID 

      DELETE FROM dbo.ezCurrentVehicle WHERE UVID IN (SELECT UVID FROM dbo.ezUsersVehicles WHERE ezUserID = @ezUserID) 
      DELETE FROM dbo.ezDriverVehicles WHERE ezUserID = @ezUserID -- Delete this Table 
      DELETE FROM dbo.ezOwnerVehicles WHERE OwnerID = @ezUserID 
      DELETE FROM dbo.ezUsersVehicles WHERE ezUserID = @ezUserID 

      DELETE FROM dbo.ezPL8Messages 
       WHERE PL8ID IN (
       SELECT PL8ID FROM dbo.ezPL8s WHERE VehicleID IN (SELECT VehicleID FROM dbo.ezVehicles WHERE CreatedBy = @ezUserID)) 

      DELETE FROM dbo.ezPL8s WHERE VehicleID IN (SELECT VehicleID FROM dbo.ezVehicles WHERE CreatedBy = @ezUserID) 

      DELETE FROM dbo.ezPL8s_Vehicles WHERE VehicleID IN (SELECT VehicleID FROM dbo.ezVehicles WHERE CreatedBy = @ezUserID) 

      DELETE FROM dbo.ezVehicles WHERE CreatedBy = @ezUserID 

      DELETE FROM dbo.ezImages_Users 
      WHERE ImageID IN (SELECT ImageID FROM dbo.ezImages 
           WHERE UploadedBy = @ezUserID) 

      DELETE FROM dbo.ezImages_Users 
      WHERE ezUserID = @ezUserID 

      DELETE FROM dbo.ezImages 
      WHERE UploadedBy = @ezUserID 

      DELETE FROM dbo.ezPets 
      WHERE ezUserID = @ezUserID 

      DELETE FROM dbo.ezAccounts 
      WHERE CPID IN (SELECT CPID FROM dbo.ezCompany_People WHERE ezUserID = @ezUserID) 

      DELETE FROM dbo.ezCompany_People 
      WHERE ezUserID = @ezUserID   

      DELETE FROM dbo.ezMedicals 
      WHERE ezUserID = @ezUserID 

      DELETE FROM dbo.ezVehicles WHERE CreatedBy = @ezUserID 

      DELETE FROM dbo.ezParentChildren WHERE ParentID = @UserID OR ChildID = @UserID 
      DELETE FROM dbo.ezEmergencyContacts WHERE ezUserID = @ezUserID 

      DELETE FROM dbo.ezDriveThrus_Customers WHERE ezUserID = @ezUserID 

      DELETE FROM dbo.ezRelationshipsP2P WHERE RelFromID = @UserID OR RelToID = @UserID 

      DELETE FROM [dbo].[ezPL8Meaning] WHERE ezUserID = @ezUserID 

      DELETE FROM dbo.ezUsers WHERE UserID = @UserID 

      DELETE FROM dbo.aspnet_PersonalizationPerUser WHERE UserID = @UserID 
      DELETE FROM dbo.aspnet_Profile WHERE UserID = @UserID 
      DELETE FROM dbo.aspnet_UsersInRoles WHERE UserID = @UserID 

      DELETE FROM dbo.aspnet_Membership WHERE UserID = @UserID  

      DELETE FROM dbo.aspnet_Users WHERE UserID = @UserID  

    COMMIT TRANSACTION; 
END TRY 

BEGIN CATCH 
    SELECT ERROR_NUMBER(), ERROR_MESSAGE(); 
    IF @@TRANCOUNT > 0 
     ROLLBACK TRANSACTION; 

    RAISERROR('Error', 16, 1) 
    RETURN 0 
END CATCH 

END 






GO