我的关系非常简单,我的模型看起来像这样:
public class Project
{
[PrimaryKey, AutoIncrement]
public int ID { get; set; }
public string Name { get; set; }
[ForeignKey(typeof(User))]
public int ProjectManagerID { get; set; }
[ManyToOne]
public User ProjectManager { get; set; }
}
public class User
{
public string Login { get; set; }
[OneToMany]
public List<Project> Projects { get; set; }
}
问题在于,我可以轻松地保存项目,引用用户而不保存用户,并且我没有得到任何约束违规异常。
database.Insert(new Project
{
Name = "aaa",
ProjectManagerID = 8
});
我甚至可以使用无效的用户ID查询我的项目,但我没有存储用户表中的任何记录。另一个有趣的事情是,当我打开这个数据库时,我无法在我的SQLite管理工具中存储上面的行,所以我确信我的数据库模式是正常的。
在带有sqlite-net-extensions的sqlite-net PCL库中这是正常的吗?
更新: 我的sqlite版本是3.8.7.4
答案 0 :(得分:3)
是的,这很正常。 SQLite-Net Extensions建立在SQLite-Net之上,它不支持外键约束,因此在数据库层没有声明外键。
使用核心SQLite-Net方法,[ForeignKey]
属性只是一个没有任何限制的整数属性,因此您可以随意修改它而不会出现运行时错误。
如果您的项目需要数据库层的外键约束,您可以使用Execute
方法将约束添加到您想要的列。
<强>更新强>
SQLite中默认禁用外键。要在SQLite-Net中启用外键,您必须将以下代码添加到程序的开头。此语句不会保留在数据库中,并且必须在每次应用程序启动时执行:
database.Execute("PRAGMA foreign_keys = ON");
要检查是否已启用,您可以使用PRAGMA foreign_keys
:
int result = database.ExecuteScalar<int>("PRAGMA foreign_keys");
if (result == 1) {
// Foreign keys enabled
}
启用后,您可以将外键添加到表声明(sqlite doesn't support adding constraints on ALTER
statements),如下所示:
CREATE TABLE child (
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT,
FOREIGN KEY (parent_id) REFERENCES parent(id)
);
显然,手动创建表会强制您不要使用SQLite-Net CreateTable
语句。
答案 1 :(得分:0)
问题解决了。我忘了将我的数据库从Resources文件夹(作为模板)复制到app data文件夹,所以从技术上讲,我的数据库是由SQLite-Net创建的,没有任何外键。谢谢你的帮助