【问题标题】:Using SQLAdapter.Update(Dataset) Throws error "No primary key in select command"使用 SQLAdapter.Update(Dataset) 引发错误“选择命令中没有主键”
【发布时间】:2011-07-12 18:16:25
【问题描述】:

简而言之,C# 向我抛出“不支持不返回任何键列信息的 SelectCommand 的 UpdateCommand 的动态 SQL 生成”,而有问题的表确实有一个主键(标识,因为它是 MSSQL)。

我的代码如下:

       void loaddata()
    {
        try
        {
            DS = new DataSet();
            sqladapt = new SqlDataAdapter("SELECT servicetag,name,defect,primkey FROM " + Properties.Settings.Default.DBtableLaptops + "", sqlcon);
            sqladapt.FillSchema(DS, SchemaType.Source);
            sqladapt.Fill(DS);
            commandBuilder = new SqlCommandBuilder(sqladapt);
            DT = DS.Tables[0];
            Laptops_datagridview.DataSource = DT; //I'm using a datagridview to edit the data.
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

    }
    void savedata()
    {
        //Doesn't work yet.
        try
        {
            sqladapt.Update(DS); // <-- Throws the aforementioned error.
            sqladapt.Dispose();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

数据加载等工作正常,添加新行也可以,并保存它。但是每当我更新或删除一行时,它都会引发错误。 Primkey 是我的主键,它是一个自动递增的整数。

我整天都在谷歌搜索,但无济于事,人们通常遇到的问题是一开始没有定义主键,但这里不是这种情况。

任何输入都将不胜感激,我已经进行了大约 6 个小时的猎枪调试。

编辑: 有问题的表的创建语句如下:

CREATE TABLE [dbo].[laptopregistratieDB_laptops](
    [Servicetag] [text] NOT NULL,
    [Name] [text] NOT NULL,
    [Defect] [bit] NOT NULL,
    [primkey] [int] IDENTITY(1,1) NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

【问题讨论】:

  • PrimKey 实际上是主键吗? IDENTITY 和 Primary Key 是两个独立的概念。您能否从 Management Studio 编写表格并发布 CREATE TABLE/ALTER TABLE 语句?
  • 我不知道它有什么不同,我已经习惯了 MySQL,当我尝试在 MSSQL 中创建数据库时它不起作用,经过一些谷歌搜索后发现我应该使用“标识符” ' 代替..

标签: c# .net sql primary-key dynamic-sql


【解决方案1】:

您实际上在表中有主键吗?如果是,检查是否设置了主键?查看属性DS.DataTables[0].PrimaryKey

DataSet 内的DataTable 中设置主键。您可以执行以下操作:

DS.DataTables[0].PrimaryKey  = DS.DataTables[0].DataColumns[3];

这将为更新设置主键。

【讨论】:

  • DS.Tables[0].PrimaryKey 确实没有设置,但是,我之前设置了它,甚至由于某种原因导致我加载数据。我会尝试一下。跨度>
  • 如果主键是文本字段(例如 NVarChar),如果最大长度是(MAX)而不是数字,可能会抛出错误
【解决方案2】:

您实际上需要将 primkey 列设为主键:

ALTER TABLE [dbo].[laptopregistratieDB_laptops]
   ADD CONSTRAINT PK_laptopregistratieDB_laptops PRIMARY KEY (primkey)

创建表时也可以指定这样的约束:

CREATE TABLE [dbo].[laptopregistratieDB_laptops](
    [Servicetag] [text] NOT NULL,
    [Name] [text] NOT NULL,
    [Defect] [bit] NOT NULL,
    [primkey] [int] IDENTITY(1,1) NOT NULL,
    constraint PK_laptopregistratieDB_laptops PRIMARY KEY (primkey)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

或者,如果您希望 SQL Server 随机生成约束名称(不推荐,但有些人会这样做):

CREATE TABLE [dbo].[laptopregistratieDB_laptops](
    [Servicetag] [text] NOT NULL,
    [Name] [text] NOT NULL,
    [Defect] [bit] NOT NULL,
    [primkey] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

如果您使用表设计器应用主键约束,SQL Server 也会随机命名该约束(右键单击要为主键的列旁边,选择“设置主键”)

所有这些选项也可用于指定多列主键,[primkey] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY 变体除外。 (在设计器场景中,您必须在右键单击之前突出显示多行)。

【讨论】:

  • 我爱你。这就像一个魅力,我不知道 MSSQL 的身份与主键不同,我只是认为这又是微软的噱头之一。再次感谢!
【解决方案3】:

行错误:" sqladapt = new SqlDataAdapter("SELECT servicetag,name,defect,primkey FROM ...,因为在您的选择查询中不包括主键或唯一字段。

您需要通过在表中添加主字段来修复您的选择 SQL。例如:

sqladapt = new SqlDataAdapter("SELECT ID, servicetag,name,defect,primkey FROM "

希望有帮助!!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2012-08-26
    相关资源
    最近更新 更多