C# 如何为现有 table 列创建主键

C# How create primary key to existing table column

我想请求你的帮助。问题是我试图关联两个表,所以我需要在每个 "id" 列的表上创建主键,但我在这一行

上收到错误
ds.Relations.Add(dr);

错误:

This constraint cannot be enabled as not all values have corresponding parent values.

(西班牙语中的原始错误 = No se puede habilitar esta restricción ya que todos los valores no tienen los valores primarios correspondientes.

我做错了什么?

OdbcDataAdapter sdata = new OdbcDataAdapter("SELECT * FROM componentes WHERE nombre_componente ILIKE '%" + buscar + "%'", conn);
OdbcDataAdapter sdata2 = new OdbcDataAdapter("SELECT * FROM proveedores WHERE nombre_empresa ILIKE '%" + buscar + "%'", conn);

DataSet ds = new DataSet();

DataTable dtbl = new DataTable("dtbl");
DataTable dtbl2 = new DataTable("dtbl2");

sdata.Fill(dtbl);
sdata2.Fill(dtbl2);

ds.Tables.Add(dtbl);
ds.Tables.Add(dtbl2);

dtbl.PrimaryKey = new DataColumn[] { dtbl.Columns["id"] };
dtbl2.PrimaryKey = new DataColumn[] { dtbl2.Columns["id"] };

DataRelation dr = new DataRelation("provcomp",
                ds.Tables["dtbl"].Columns["id_prov_comp"],
                ds.Tables["dtbl2"].Columns["id"]);

ds.Relations.Add(dr);
ds.AcceptChanges();

提前致谢。

这里的问题是你的数据。您正在为每个 table 添加主键,然后尝试使用外键 link 它们。

但是,从您收到的错误消息来看,您似乎正试图 link dtbl 到 dtbl2 中不存在的 ID。

我会尝试执行 SQL 查询以找出问题记录所在的位置,然后选择添加 "parent"、更改父项或删除记录。

SELECT * FROM componentes WHERE id_prov_comp NOT IN (SELECT ID FROM proveedores )

主键没问题 - 您已经使用以下几行成功创建了它们:

dtbl.PrimaryKey = new DataColumn[] { dtbl.Columns["id"] };
dtbl2.PrimaryKey = new DataColumn[] { dtbl2.Columns["id"] };

问题出在 DataRelation 中(如异常所示)。 DataRelation相当于数据库FK(外键)。使用的构造函数的签名如下所示:

public DataRelation(
    string relationName,
    DataColumn parentColumn,
    DataColumn childColumn
)

我认为您做错的是指定了错误的列 - parentColumn 应该指向被引用的 table 而 childColumn - table 引用它。

简单的改成:

DataRelation dr = new DataRelation("provcomp",
    ds.Tables["dtbl2"].Columns["id"],
    ds.Tables["dtbl"].Columns["id_prov_comp"]);

如果真的关联正确,问题应该就解决了。

编辑: 如果父 table 不包含子 table 的所有键,您可以考虑使用此构造函数 overload 并传递 createConstraints = false,这将防止异常,但请注意,某些子记录将找不到它们的父记录。

DataRelation dr = new DataRelation("provcomp",
    ds.Tables["dtbl2"].Columns["id"],
    ds.Tables["dtbl"].Columns["id_prov_comp"],
    false);

父列(即主键)必须位于子列(即外键)之前。试试这个:

DataRelation dr = new DataRelation("provcomp",
            ds.Tables["dtbl2"].Columns["id"],
            ds.Tables["dtbl"].Columns["id_prov_comp"]);