【问题标题】:EF core 6.0 + SQLite foreign key constraint, meaningful error descriptionEF core 6.0 + SQLite外键约束,有意义的错误描述
【发布时间】:2023-01-13 17:16:01
【问题描述】:

我正在尝试涵盖一个大型项目,该项目具有复杂的数据库模式和大量的集成测试。对于集成测试,我使用的是 SQLite 数据库。每次违反外键约束时,我都会收到错误消息:

FOREIGN KEY constraint failed

堆栈:EntityFramework core 6.0, SQLite v 6.0

连接字符串: Data Source=:memory:;foreign keys=true

不解释,它打的是哪个外键。在实体很复杂的情况下,总是需要异常多的时间来确定它是哪个约束。 有什么方法可以使用有关外键约束已命中的信息来扩展异常? 就像是:

FOREIGN KEY constraint - ItemId failed

【问题讨论】:

  • 我认为你可以处理 DbUpdateException 并获得你想要的信息
  • @BayramEren 当我查看DbUpdateException 在 MSDN 中的条目时,我在其实体条目的只读列表中找不到任何关于违反外键的信息。
  • 我不确定,但我已经将其用于接近此的情况。值得一试:)
  • 是的,@MarkBenningfield,我看到了那个答案。然而,我希望它在过去 6 年中有所改进。

标签: c# sqlite entity-framework-core


【解决方案1】:

留给自己,当尝试使用外键提交时,SQLite 不会关闭事务 在冲突中。届时,您可以使用pragma命令查询外键状态 冲突,修复或删除它们,然后继续提交事务。

但是,SQLite 的包装器通常会在出现错误时立即处理事务,渲染 该解决方案站不住脚。在这种情况下,您必须控制包装器提供的事务。

我们假设您了解如何在 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
}

看:
defer_foreign_keys
foreign_key_check
foreign_key_list

【讨论】:

    【解决方案2】:

    @Maris 试试这个https://github.com/Giorgi/EntityFramework.Exceptions

    安装 Sqlite Extension 并尝试处理异常唯一约束异常

    【讨论】:

      猜你喜欢
      • 2020-10-18
      • 1970-01-01
      • 1970-01-01
      • 2021-11-02
      • 2021-12-28
      • 1970-01-01
      • 2021-04-07
      • 2014-01-17
      相关资源
      最近更新 更多