2012-07-16 58 views
1

我無法將相關行插入到我的數據庫中。當我在ASP.NET應用程序的數據庫中插入新對象時,出現外鍵違例錯誤,而在控制檯應用程序中,我沒有。數據集更新,外鍵違規(但僅限於ASP.NET?)

下面是重現該問題的步驟:

  1. 創建一個新的數據庫上運行下面的T-SQL腳本:

    create table dbo.[Groups] (
        GroupId int identity primary key, 
        Name nvarchar(64) not null 
    ) 
    
    create table dbo.[Objects] (
        ObjectId int identity primary key, 
        GroupId int not null foreign key references [Groups] on delete cascade, 
        Name nvarchar(64) not null 
    ) 
    
  2. 設置名爲「ConsoleProgram一個C#控制檯應用程序」。

  3. 將一個名爲「dsObjects」的新DataSet添加到項目中。
  4. 將服務器資源管理器中的「組」和「對象」表拖放到設計器中。
  5. 編輯兩個表之間的關係,並將關係設置爲「關係和外鍵約束」並將更新規則設置爲「級聯」。
  6. 將以下代碼到「主」:

    // (assuming appropriate using statement for dsObjectsTableAdapters) 
    var ds = new dsObjects(); 
    var mgr = new dsObjectsTableAdapters.TableAdapterManager { 
        GroupsTableAdapter = new GroupsTableAdapter(), 
        ObjectsTableAdapter = new ObjectsTableAdapter() 
    };    
    mgr.GroupsTableAdapter.Fill(ds.Groups); 
    mgr.ObjectsTableAdapter.Fill(ds.Objects); 
    
    var row = ds.Groups.AddGroupsRow("Fruits"); 
    ds.Objects.AddObjectsRow(row, "Apple"); 
    ds.Objects.AddObjectsRow(row, "Banana"); 
    ds.Objects.AddObjectsRow(row, "Orange"); 
    
    mgr.UpdateAll(ds); 
    
  7. 運行程序和驗證新的行被插入到相應的表:

    GroupId  Name 
    ----------- ------- 
    1   Fruits 
    
    (1 row(s) affected) 
    
    ObjectId GroupId  Name 
    ----------- ----------- ------- 
    1   1   Apple 
    2   1   Banana 
    3   1   Orange 
    
    (3 row(s) affected) 
    
  8. 刪除新創建的數據。

  9. 關閉解決方案。
  10. 創建一個新的ASP.NET Web應用程序。
  11. 重複步驟3-5。
  12. 將步驟6中的代碼插入到Default.aspx的Page_Load函數中。
  13. 運行該程序。
  14. 請注意關於外鍵違例(如果有)的例外情況。
  15. 再次運行控制檯程序並注意數據已成功創建。
  16. 重新創建數據庫並再次運行ASP.NET應用程序並注意相同的異常。

我已經嘗試使用UpdateAll方法按順序更新表,兩個項目中都有相同的結果。

我完全喪失了爲什麼這可以在ConsoleApplication中工作,而不是在ASP.NET應用程序中工作。有任何想法嗎?

回答

2

好的,經過一番探索後,我找到了解決問題的辦法。在線程http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataset/thread/4d10fe87-2de8-42a8-8ef9-b9d46c0fd28d中暗示爲了在數據集中正確更新標識列,必須在INSERT語句後使用SELECT語句。在瀏覽「TableAdapter配置嚮導」後,我發現在「高級選項」下有一個「刷新數據表」選項,它在INSERT後添加適當的SELECT語句。對於我來說一些未知的原因,默認情況下,這在ASP.NET Web應用程序中未被選中,並且在控制檯應用程序中默認被選中。

選中此選項後,數據集更新按預期工作。

1

我在我的電腦上運行您的代碼,並在控制檯應用程序中出現以下錯誤。

Cannot make this change because constraints are enforced on relation FK__Objects__GroupId__2C3393D0, and changing this value will strand child rows. 

一件事下面的代碼var row = ds.Groups.AddGroupsRow("Fruits");返回包含組ID和姓名時,我調試它,我發現,添加第一個記錄後,它包含了羣ID = -1和名稱=水果數據行。一個ID如何可以= -1?

+0

是的,我也注意到了這一點。它們似乎是佔位符,直到它們被插入到數據庫中,並根據標識列獲得新的ID。但是,如果我要從數據庫中除去外鍵約束,那麼代碼「工作」,除了「對象」中新行的GroupId列以外,不會被轉換爲「組」中的相應新行;他們被設置爲負數。 – Thomas 2012-07-17 15:20:36

+0

經過進一步的研究,我發現表中的標識列是自動生成的(-1,-1),這會導致數據集標記新的行並遞減負數。 – Thomas 2012-07-17 17:18:30

+0

@Thomas良好的工作。 – 2012-07-17 17:24:49