为了账号安全,请及时绑定邮箱和手机立即绑定

SQLite 单元测试中的 FOREIGN KEY 约束失败

SQLite 单元测试中的 FOREIGN KEY 约束失败

C#
慕标5832272 2021-12-05 14:49:25
我有一个数据库,它有两个不同的路径到某个实体,一个路径DeleteBehavior.Cascade和另一个路径,DeleteBehavior.Restrict以避免在数据库创建时出现多个级联路径错误。当在内存中使用 IIS Express 和 Visual Studio 的 SQL Server 在本地运行时,这正如我预期的那样工作,但在测试相同功能的单元测试中抛出错误。例子:public class Account{    public string Id { get; set; }}每个帐户都可以订阅:public class Subscription{    public string Id { get; set; }    // relationships    public string AccountId { get; set; }    public Account Account { get; set; }}帐户和订阅都可以有联系人(这可能没有多大意义,但这只是一个例子,实际上我的模型更复杂,但基本上归结为这个):public class Contact{    public string Id { get; set; }    // relationships    public string AccountId { get; set; }    public Account Account { get; set; }    public string SubscriptionId { get; set; }    public Subscription Subscription { get; set; }}如果帐户或订阅被删除,我希望删除任何联系人。这是我的联系人模型构建器配置:public void Configure(EntityTypeBuilder<Contact> entity){    entity.HasOne(e => e.Account)        .WithMany()        .HasForeignKey(e => e.AccountId)        .OnDelete(DeleteBehavior.Restrict);    entity.HasOne(e => e.Subscription)        .WithMany()        .HasForeignKey(e => e.SubscriptionId)        .OnDelete(DeleteBehavior.Cascade);}订阅配置:public void Configure(EntityTypeBuilder<Subscription> entity){    entity.HasOne(e => e.Account)        .WithMany()        .HasForeignKey(e => e.AccountId)        .OnDelete(DeleteBehavior.Cascade);}这个想法是,当一个帐户被删除时,这将通过Cascade删除行为删除订阅,这将删除联系人,Restrict帐户和联系人之间的行为解决了“多级联路径”错误。这在我本地运行时有效,我可以删除一个帐户并删除所有订阅和联系人,没有错误。问题在于单元测试(使用 xUnit),它在内存中使用 SQLite。我想测试删除帐户会删除所有联系人:[Fact]public async Task DeleteAccount_ContactIsDeleted(){    using (var factory = new ContextFactory()) // same connection will be used within using block    {        using (var context = factory.CreateContext())        {            await context.SeedDatabaseOneContactAsync(); // inserts account, subscription and contact into database        }
查看完整描述

3 回答

?
繁花如伊

TA贡献2012条经验 获得超12个赞

默认情况下,SQLite 中禁用 FK 约束。http://www.sqlite.org/foreignkeys.html

默认情况下禁用外键约束(为了向后兼容),因此必须为每个数据库连接单独启用。(但是请注意,SQLite 的未来版本可能会更改,以便默认启用外键约束。细心的开发人员不会对默认情况下是否启用外键做出任何假设,而是会根据需要启用或禁用它们。)

您可以通过添加foreign keys=true到连接字符串来启用它们。(data source=test.db;foreign keys=true完整示例)


查看完整回答
反对 回复 2021-12-05
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

老问题,但我有同样的问题。

到目前为止,我认为它与作为字符串的列有关,您不能将其设置为可空值类型。例如。细绳?如果你把它改成 Guid?或int?那么你没有同样的问题。

我认为这可能是实体框架中的一个错误,它认为该列实际上是不可为空的。


查看完整回答
反对 回复 2021-12-05
?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

不确定这是否是您的问题,但是当流畅的 API 关系配置与实际表结构不匹配时,我遇到了同样的错误。

在我的例子中,流畅的 API 设置了一对一的关系,但实际的底层表结构是一对多的关系。


查看完整回答
反对 回复 2021-12-05
  • 3 回答
  • 0 关注
  • 210 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信