0

2 つのテーブルを作成しました。

出版社

  • PK、PublisherId、int、not null、indentity +1
  • PublisherName、varchar(50)、null 以外

製品

  • PK、ProductId、int、null 以外、id +1
  • 製品名、varchar(50)、null 以外
  • PublisherId、int、null 以外

次に、PublisherId を接続するテーブル間に外部キー制約FK__Product__Publisherを作成しました。

このようにして、各パブリッシャーが複数の製品を持つことができる一方で、それぞれ 1 つのパブリッシャーを持つ製品をサポートしたいと考えています。それはそれと同じくらい簡単です。

ここで、C# でコンソール プロジェクトを作成し、型指定されたデータセットと 2 つの TableAdapter を追加しました。1 つは発行元を指し、もう 1 つは製品を指します。DataSet-Designer は、SQL Server から取得した内容に基づいてリレーションを自動的に追加します。

また、選択した製品の発行者と、選択した発行者のすべての製品にアクセスできるようにするプロパティも自動的に生成します。

これは私のテストコードです:

ProductTableAdapter adapter = new ProductTableAdapter();

foreach (ProductRow product in adapter.GetData())
{
    Console.WriteLine(product.PublisherRow.PublisherName);
}

ただし、これは機能しません。生成されたコードでは、プロパティ PublisherRow は次のようになります。

[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public LanguageRow PublisherRow {
    get {
        return ((PublisherRow)(this.GetParentRow(this.Table.ParentRelations["FK_Product_Publisher"])));
    }
    set {
        this.SetParentRow(value, this.Table.ParentRelations["FK_Product_Publisher"]);
    }
}

this.Table.ParentRelations には関係が含まれていません。null であり、アクセスすると NullReferenceException が発生します。

ここで何が間違っていますか?

4

1 に答える 1

2

自分の投稿に答えるのは少し奇妙に思えます。ちょっと独り言みたいです。ただし、解決策を見つけました。この問題はかなり一般的であるように思われるため、ここに投稿します。

TableAdapters を使用してデータを取得するだけでは、データベースから適切なリレーションを取得できません。リレーションシップの初期化は、データセット クラス (つまり、データセットの c'tor から呼び出される InitClass メソッド) 内で行われます。

public DbDataSet() {
    this.BeginInit();
    this.InitClass();
    ...
    this.EndInit();
}

対応する生成された InitClass メソッドは次のようになります。

private void InitClass() {
    ...
    this.relationFK_Product_Publisher= new global::System.Data.DataRelation("FK_Product_Publisher", new global::System.Data.DataColumn[] { this.tableProduct.PublisherIdColumn}, new global::System.Data.DataColumn[] { this.tablePublisher.PublisherIdColumn}, false);
    this.Relations.Add(this.relationFK_Product_Publisher);
}

これが、データセット クラス自体をインスタンス化し、fill メソッドを使用して次のようにテーブル クラスにデータを入力する必要がある理由です。

DbDataSet ds = new DbDataSet();    

ProductTableAdapter productAdapter = new ProductTableAdapter();            
productAdapter.Fill(ds.Product);

PublisherTableAdapter publisherAdapter = new PublisherTableAdapter();
publisherAdapter.Fill(ds.Publisher);

foreach (ProductRow product in ds.Product)
{                
    Console.WriteLine(product.PublisherRow.PublisherName);
}
于 2008-11-19T13:12:39.877 に答える