【问题标题】:.NET / SQLite. Inserting parent/child record; how do I get the foreign key?.NET / SQLite。插入父/子记录;我如何获得外键?
【发布时间】:2010-01-30 23:01:34
【问题描述】:

我通过 ADO.NET 2.0 Provider(SourceForce 项目)使用 VS 2008 (C#) 和 SQLite。

应用程序使用的数据库包含“employees”(父)和“employmentHistory”(子)数据表。 “eploymentHistory”数据表应该包含任何给定员工从第一天起的所有工作合同(例如,升职将产生新合同)。

很遗憾 SQLite 不支持外键,所以我需要自己处理数据的一致性。

employmentHistory 数据库包含 “id INTEGER PRIMARY KEY NOT NULL, employeeID INTEGER...” 列 所以很明显,employeeID 将引用employess.ID,即employees 表中的主键。它标识了它是谁的合同。

我正在编写一个添加新员工的方法。每个人都至少有一份合同(第一份),因此添加新员工与添加合同有关。

方法如下:

internal static void AddNewEmployee(Employee e, ContractChange c)
    {
        SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adapter);
        var insert = new SQLiteCommand(connection);
        insert.CommandText = @"INSERT INTO employees VALUES ( null, @firstName, @lastName, @phone, @mobile, null, null, ";
        insert.CommandText+= @"@birthDate, @sex, @address, @nin, null, null); ";
        insert.Parameters.AddWithValue("firstName", e.info.name);
        insert.Parameters.AddWithValue("lastName", e.info.surname);
        insert.Parameters.AddWithValue("phone", e.info.phone);
        insert.Parameters.AddWithValue("mobile", e.info.mobile);

        insert.Parameters.AddWithValue("birthDate", e.info.DOB);
        insert.Parameters.AddWithValue("sex", e.info.sex);
        insert.Parameters.AddWithValue("address", e.info.address);
        insert.Parameters.AddWithValue("nin", e.info.NIN);

        insert.CommandText += @"INSERT INTO employmentHistory VALUES ( null, null, @startDate, 'true', @position, @contractHrs, ";
        insert.CommandText += @"@holidayAllowance, @comments, null); ";
        insert.Parameters.AddWithValue("startDate", c.date);
        insert.Parameters.AddWithValue("position", (int)c.role);
        insert.Parameters.AddWithValue("contractHrs", (int)c.contractHrs);
        insert.Parameters.AddWithValue("holidayAllowance", c.holidayAllowance);
        insert.Parameters.AddWithValue("comments", c.comments);                        

        DataTable employees = dataset.Tables[0];
        var datarowEmp = employees.NewRow();
        datarowEmp = e.ToDataRow(datarowEmp);
        employees.Rows.Add(datarowEmp);

        DataTable employmentHistory = dataset.Tables[1];
        var datarowContract = employmentHistory.NewRow();
        datarowContract = c.ToDataRow(datarowContract);
        employmentHistory.Rows.Add(datarowContract);

        adapter.UpdateCommand = insert;
        adapter.InsertCommand = insert;
        adapter.SelectCommand = new SQLiteCommand("SELECT * FROM employees; SELECT * FROM employmentHistory;", connection);
        adapter.Update(dataset);


    }

所以我想我会通过快速更新“手动”设置员工 ID。但是 - 我怎么知道分配给我刚刚添加的员​​工的 ID??

令人惊讶的是(对我来说),即使在 SQLiteDataAdapter 更新数据之后(我在方法的最后设置了一个断点),这些信息仍然不在数据集中。该字段仍然为空。然而 SQLite 确实在某些时候赋予了唯一编号,因为没有抛出异常并且员工确实获得了主键(我在 SQLite 数据库浏览器中看到了数据库)。

所以我不能自动执行,也无法手动执行 - 我应该如何强制执行数据库一致性? :(

【问题讨论】:

  • 仅供参考,gender 被认为比 sex 更合适

标签: c# .net sqlite foreign-keys parent-child


【解决方案1】:

last_insert_rowid

你可以在一行中实现它:

cmd.CommandText = "INSERT INTO .. VALUES(..);SELECT last_insert_rowid() AS [ID]";
strId = cmd.ExecuteScalar().ToString()

更新:

您可能还希望将两个插入包含在一个事务中,因此如果其中一个失败,您可以回滚整个插入,并防止数据库中的数据损坏。

【讨论】:

  • 好吧,我检查了一下,它实际上就像这样简单:“插入就业历史值(null,last_insert_rowid()......”但是我知道如果添加员工,last_insert_rowid()将返回 0无论出于何种原因出错,那么在最好的情况下,我最终会得到孤立的记录,感谢您的帮助!
【解决方案2】:
select last_insert_rowid(); 

【讨论】:

    猜你喜欢
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    • 2011-05-17
    • 1970-01-01
    相关资源
    最近更新 更多