【发布时间】:2019-01-26 10:59:09
【问题描述】:
我有一个数据库,其中有两个不同路径到某个实体,一个路径为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行为解决了“多级联路径”错误.
这在我在本地运行时有效,我可以删除一个帐户并删除所有订阅和联系人,没有错误。问题在于在内存中使用 SQLite 的单元测试(使用 xUnit)。我想测试一下删除账号会删除所有联系人:
[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
}
using (var context = factory.CreateContext())
{
Assert.Single(context.Contacts);
Assert.Single(context.Subscriptions);
Assert.Single(context.Accounts);
var account = await context.Accounts.SingleAsync();
context.Remove(account);
await context.SaveChangesAsync();
Assert.Empty(context.Contacts);
Assert.Empty(context.Accounts);
Assert.Empty(context.Subscriptions);
}
}
}
但是这会引发以下错误
消息:Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。 ---- Microsoft.Data.Sqlite.SqliteException : SQLite 错误 19: 'FOREIGN KEY 约束失败'。
上线
await context.SaveChangesAsync();
我想知道这是否是 SQLite 的问题,或者我的模型或配置是否有问题?
注意:我使用的是 Entity Framework Core 2.1.1,这些关系是必需的(不能为空)。
【问题讨论】:
-
如果对您有帮助,请将答案标记为已接受。
标签: c# sqlite entity-framework-core xunit.net