1

関連する行をデータベースに挿入できません。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. テーブル "Groups" と "Objects" をサーバー エクスプローラーからデザイナーにドラッグします。
  5. 2 つのテーブル間のリレーションを編集し、リレーションを「リレーションと外部キー制約の両方」に設定し、ルールを「カスケード」に更新します。
  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 アプリケーションでは機能しない理由について、私は完全に途方に暮れています。何か案は?

4

2 に答える 2

2

さて、いくつか検索した後、問題の解決策を見つけました。スレッドhttp://social.msdn.microsoft.com/Forums/en-US/adodotnetdataset/thread/4d10fe87-2de8-42a8-8ef9-b9d46c0fd28dでは、ID 列を正しく更新するために、 INSERT ステートメントの後に SELECT ステートメントを使用する必要があります。「TableAdapter 構成ウィザード」を調べたところ、「詳細オプション」の下に、INSERTions の後に適切な SELECT ステートメントを追加する「データ テーブルを更新する」オプションがあることがわかりました。なんらかの理由で、これは ASP.NET Web アプリケーションではデフォルトでチェックされておらず、コンソール アプリケーションではデフォルトでチェックされていました。

このオプションをオンにすると、データセットの更新が期待どおりに機能します。

于 2012-07-17T17:16:14.907 に答える
1

PC でコードを実行すると、コンソール アプリケーションで次のエラーが発生しました。

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

もう 1 つ、次のコードvar row = ds.Groups.AddGroupsRow( "Fruits" );は、デバッグ時に GroupID と Name を含むデータ行を返します。最初のレコードを追加した後、GroupID = -1 と Name = Fruits が含まれていることがわかりました。ID はどのようにして = -1 になりますか?

于 2012-07-17T09:46:51.060 に答える