ManyToOne约束不起作用

时间:2015-02-09 10:54:07

标签: c# xamarin sqlite-net sqlite-net-extensions

我的关系非常简单,我的模型看起来像这样:

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

2 个答案:

答案 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创建的,没有任何外键。谢谢你的帮助