0

我创建了两个表:

出版商

  • PK, PublisherId, int, not null, indentity +1
  • PublisherName,varchar(50),不为空

产品

  • PK, ProductId, int, not null, identity +1
  • 产品名称,varchar(50),不为空
  • PublisherId,整数,不为空

然后我在连接 PublisherId 的那些表之间创建了一个外键约束FK__Product__Publisher 。

这样,我想支持每个都有一个发布者的产品,而每个发布者可以有多个产品。就这么简单。

现在我在 C# 中创建了一个控制台项目,添加了一个类型化数据集和两个 TableAdapter。一个指向 Publisher 一个指向 Product。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 回答