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

我有一个数据库,它有两个不同的路径到某个实体,一个路径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

        }


慕标5832272
浏览 212回答 3
3回答

繁花如伊

默认情况下,SQLite 中禁用 FK 约束。http://www.sqlite.org/foreignkeys.html默认情况下禁用外键约束(为了向后兼容),因此必须为每个数据库连接单独启用。(但是请注意,SQLite 的未来版本可能会更改,以便默认启用外键约束。细心的开发人员不会对默认情况下是否启用外键做出任何假设,而是会根据需要启用或禁用它们。)您可以通过添加foreign keys=true到连接字符串来启用它们。(data source=test.db;foreign keys=true完整示例)

qq_花开花谢_0

老问题,但我有同样的问题。到目前为止,我认为它与作为字符串的列有关,您不能将其设置为可空值类型。例如。细绳?如果你把它改成 Guid?或int?那么你没有同样的问题。我认为这可能是实体框架中的一个错误,它认为该列实际上是不可为空的。

慕尼黑的夜晚无繁华

不确定这是否是您的问题,但是当流畅的 API 关系配置与实际表结构不匹配时,我遇到了同样的错误。在我的例子中,流畅的 API 设置了一对一的关系,但实际的底层表结构是一对多的关系。
打开App,查看更多内容
随时随地看视频慕课网APP