EF core 6.0 + SQLite外键约束,有意义的错误描述

w46czmvw  于 2023-01-13  发布在  SQLite
关注(0)|答案(2)|浏览(256)

bounty将于明天到期。回答此问题可获得+100的声望奖励。Maris希望吸引更多人关注此问题。

我正在尝试覆盖一个大型项目,有复杂的数据库架构,有大量的集成测试。对于集成测试,我使用SQLite数据库。每次当外键约束被违反时,我都会得到一个错误:

FOREIGN KEY constraint failed

堆叠:EntityFramework core 6.0, SQLite v 6.0
连接字符串:Data Source=:memory:;foreign keys=true
如果没有解释,它命中的是哪个外键。在实体很复杂的情况下,它总是需要异常的时间来找出它是哪个约束。有没有办法扩展异常,提供命中哪个外键约束的信息?类似于:

FOREIGN KEY constraint - ItemId failed
jq6vz3qz

jq6vz3qz1#

如果不加干预,SQLite不会在外键冲突的情况下尝试提交事务时关闭事务。此时,您可以使用pragma命令查询冲突外键的状态,修复或删除它们,然后继续提交事务。
然而,SQLite的 Package 器通常在出现错误时立即处理事务,这使得解决方案无法成立,在这种情况下,您必须控制 Package 器提供的事务。
我们假设您知道如何在EFCore中管理适合您特定场景的事务(外部、跨上下文等),本示例仅使用单个上下文中的事务。

using var context = new PersonContext();
using var transaction = context.Database.BeginTransaction();

try
{
  // set all foreign key enforcement to "DEFERRED"
  // not strictly necessary for a single transaction
  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
}

参见:
延迟外键
外键检查
外键列表

mxg2im7a

mxg2im7a2#

@Maris试试这个https://github.com/Giorgi/EntityFramework.Exceptions
安装SqlLite扩展并尝试使用UniqueConstraintException处理异常

相关问题