【问题标题】:ConstraintException when querying SQlite database with C#使用 C# 查询 SQlite 数据库时出现 ConstraintException
【发布时间】:2011-06-28 07:24:10
【问题描述】:

我希望有人能够帮助我解决我的 SQLite 数据库问题。

使用 C# 查询我的 SQLite 数据库时,我收到了 ConstraintException。完整的异常消息是“Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.”我最初使用 access 构建了这个数据库,效果很好,但由于各种原因,我不得不使用 SQLite 重新创建它。

提供一些背景知识 - 这是一个简单的状态调度程序。每个Status 都有一个关联的AccountSchedule。我意识到 StatusesSchedule 是 1:1 的关系,可以在同一个表中,但为了让程序进一步发展,我将它们分成两个表。

请参阅下面的表格脚本的精简版本(这足以重现问题)。

PRAGMA foreign_keys = ON;

CREATE TABLE Accounts
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
Name char(100));

CREATE TABLE Statuses
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
AccountId INTEGER REFERENCES Accounts(ID) ON DELETE CASCADE,
Text char(140));

CREATE TABLE Schedule
(ID INTEGER PRIMARY KEY REFERENCES Statuses(ID) ON DELETE CASCADE,
StartDate char(255),
Frequency INT);

在创建两个 Statues 并将它们关联到同一个 Account 之前,我没有任何问题。

Accounts
ID  Name
1   Fred Blogs

Statuses
ID AccountId Text
1         1          “Some text”
2         1          “Some more text”

Schedule
ID    StartDate     Frequency
1     16/02/2011        1
2     16/02/2011        1

我正在使用的引发异常的选择语句是:

SELECT Statuses.Id, Statuses.Text, Accounts.Id, Accounts.Name, Schedule.StartDate, Schedule.Frequency
FROM [Statuses], [Accounts], [Schedule]
WHERE Statuses.AccountId = Accounts.Id AND Statuses.Id = Schedule.Id

如果我运行相同的查询,但删除“Accounts.Id”列,则查询工作正常。

下面是我正在使用的 C# 代码,但我认为这不是问题

public DataTable Query(string commandText)
    {

        SQLiteConnection sqliteCon = new SQLiteConnection(ConnectionString);
        SQLiteCommand sqliteCom = new SQLiteCommand(commandText, sqliteCon);
        DataTable sqliteResult = new DataTable("Query Result");

        try
        {
            sqliteCon.Open();
            sqliteResult.Load(sqliteCom.ExecuteReader());
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            sqliteCon.Close();
        }

        return sqliteResult;

    }

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: c# database database-design sqlite


    【解决方案1】:

    由于状态表和计划表中的 ID 列而发生错误。如果它们不重要,请从两个表中删除列。

    【讨论】:

    • 感谢您的回复。 Id 列很重要,因为我需要将计划链接到状态。每个状态都有相应的时间表。例如,ID 为 1 的状态链接到 ID 为 1 的计划。计划 ID 是外键。此外,我不确定问题是否与计划表有关,因为问题仅在我选择 [Account.Id] 和 [Status.Id] 时才会出现
    【解决方案2】:

    我找到了解决这个问题的方法。如果我从 Schedule 表而不是 Accounts 表中选择 AccountId,则不会引发异常。我似乎无法运行包含两个唯一主键列的 SELECT 语句。

    所以不是

    SELECT Statuses.Id, Statuses.Text, Accounts.Id, Accounts.Name, Schedule.StartDate, Schedule.Frequency
    FROM [Statuses], [Accounts], [Schedule]
    WHERE Statuses.AccountId = Accounts.Id AND Statuses.Id = Schedule.Id
    

    我跑

    SELECT Statuses.Id, Statuses.Text, Statuses.AccountId, Accounts.Name, Schedule.StartDate, Schedule.Frequency
    FROM [Statuses], [Accounts], [Schedule]
    WHERE Statuses.AccountId = Accounts.Id AND Statuses.Id = Schedule.Id
    

    【讨论】:

      【解决方案3】:

      我首先通过仅读取架构来解决此问题,然后清除数据表的约束,然后再次读取数据。 像这样:

      DataSet DS = new DataSet();
      mytable = new DataTable();
      DS.Tables.Add(mytable);
      DS.EnforceConstraints = false;
      SQLiteCommand command = DBconnection.CreateCommand();
      command.CommandText = "select * from V_FullView";
      SQLiteDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly);
      mytable.Load(reader);
      mytable.Constraints.Clear();
      reader = command.ExecuteReader();
      mytable.Load(reader);
      reader.Close();
      

      我的 V_FullView 是合并了 4 个不同表的视图。似乎约束是第一个合并表的约束(名称在那个表上是唯一的,但在视图中复制了多次)

      【讨论】:

        猜你喜欢
        • 2013-04-29
        • 1970-01-01
        • 2012-06-20
        • 2016-04-18
        • 2020-08-26
        • 1970-01-01
        • 2013-10-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多