Mar*_*ris 7 c# sqlite entity-framework-core
我试图涵盖一个大型项目,具有复杂的数据库模式和大量的集成测试。对于集成测试,我使用 SQLite 数据库。每次违反外键约束时,我都会收到错误:
FOREIGN KEY constraint failed
Run Code Online (Sandbox Code Playgroud)
堆:EntityFramework core 6.0, SQLite v 6.0
连接字符串:
Data Source=:memory:;foreign keys=true
没有解释,它击中了哪个外键。在实体很复杂的情况下,总是需要异常多的时间来找出它是哪个约束。有什么方法可以使用有关外键约束已命中的信息来扩展异常吗?就像是:
FOREIGN KEY constraint - ItemId failed
Run Code Online (Sandbox Code Playgroud)
当尝试使用冲突的外键进行提交时,SQLite 不会关闭事务。此时,您可以使用pragma命令来查询冲突外键的状态,修复或删除它们,然后继续提交事务。
然而,SQLite 的包装器通常会在出现错误时立即处理事务,从而导致该解决方案站不住脚。在这种情况下,您必须控制包装器提供的事务。
我们假设您了解如何管理 EFCore 中适合您的特定场景的事务(外部事务、跨上下文事务等)。此示例仅在单个上下文中使用事务。
using var context = new PersonContext();
using var transaction = context.Database.BeginTransaction();
try
{
// set all foreign key enforcement to "DEFERRED"
context.Database.ExecuteSql("PRAGMA defer_foreign_keys=1;");
// various CRUD operations that may involve foreign key conflicts
// read the foreign key information from the table-valued pragma functions
// `foreign_key_check` and `foreign_key_list`
string sql = @"select a.""table"" || '.'|| ""from"" from pragma_foreign_key_check a
inner join pragma_foreign_key_list(a.""table"") b on
b.id == a.fkid;";
var conflicts = context.Database
.SqlQuery<string>(sql)
.ToList();
// the list will contains strings like "tableName.fkColumn"
// handle conflicts if the list count > 0
// go ahead and commit the transaction
transaction.Commit();
}
catch (Exception)
{
// TODO: Handle failure
}
Run Code Online (Sandbox Code Playgroud)
请参阅:
defer_foreign_keysforeign_key_checkforeign_key_list
| 归档时间: |
|
| 查看次数: |
734 次 |
| 最近记录: |