gpt4 book ai didi

entity-framework - 从 Entity Framework 上下文中删除失败的更改

转载 作者:行者123 更新时间:2023-12-04 07:25:13 25 4
gpt4 key购买 nike

设想

  • 理想情况下使用 DI (Ninject) 来管理范围内的上下文/存储库,但实际上仅限于服务定位器模式,不要问。理想的例子:
    // EF code-first context
    kernel.Bind<MyDbContext>().ToSelf().InRequestScope().WithConstructorArgument("connectionString",...);

    // EF code-first repositories
    kernel.Bind<IRepository<SomeModel>>().To<EfRepository<SomeModel, MyDbContext>>().InRequestScope();
    kernel.Bind<IRepository<AuditLog>>().To<EfRepository<AuditLog, MyDbContext>>().InRequestScope();
  • 在我的服务调用中,我尝试将错误数据保存到数据库中,因此 repo/context .SaveChanges()正确失败:
    try {
    var model = new SomeModel { Name = ..., Blah = ... }
    repoSomeModels.Add(model);
    repoSomeModels.Commit(); // bad data, throws exception
    }
  • 然后,我想将这次失败的尝试记录到同一数据库中:
    catch(Exception ex) {
    repoAuditLogs.Add(new AuditLog { Action = ..., Result = ex.Message });
    repoAuditLogs.Commit();
    throw ex; // rethrow the problem so we can properly bail
    }

  • 但是,当尝试保存第二次提交( repoAuditLogs.Commit() )中的更改时,我再次遇到相同的异常。这是因为第一次尝试提交的“错误数据”仍然存在于 EF 上下文中,即使尝试失败,所以 EF 再次尝试提交错误数据,但不知道它不应该这样做。

    问题

    如何从 EF 上下文中删除失败的更改?还是我要解决这个问题?

    (更新:不要专注于我的场景的细节,即因为我有效地记录了一个错误,所以使用不同的上下文可能是合适的,但假设我只想做其他事情)

    可能的解决方案

    我偶然发现了这篇博文—— http://rundevrun.blogspot.com/2012/06/entity-framework-removing-failed.html -- 这表示您应该找到所有有问题的实体并将它们的更改标记为“已接受”,这会导致 EF 在后续提交期间“忽略”它们。这适用于我的情况,允许我保存我的审计日志并“退出”。

    然而,一位同事指出,这会导致上下文不再与其所代表的数据正确同步,因此这是一个糟糕的主意——即使对我的情况来说“没问题”(因为我要立即停止程序)如果您要继续请求(如原始帖子所建议的那样),您将冒着尝试使用“损坏”上下文的风险,并且可能会产生意想不到的副作用。

    在解决死锁的另一种情况下,他将提交显式包装在(基于代码的)事务中(EF 已经在 SQL 中执行此操作),因此他可以重新尝试它,但这并不能解决我的问题,即数据错误,而不是联系。

    我能想到的唯一其他解决方案是将我的审计保存在一个新的上下文中。理想情况下,我使用 DI/locator 将我的审计 repo 映射到不同的上下文,例如(强调 new MyDbContext 或任何应有的内容):
        kernel.Bind<IRepository<AuditLog>>().To<EfRepository<AuditLog, MyDbContext>>(new MyDbContext(...)).InRequestScope();

    但是后来我有两个上下文 float ,这似乎与首先共享上下文的观点相反。

    最佳答案

    一次SaveChanges()你的 Context 失败了应该被丢弃,因为它对任何进一步的事件都没有好处。

    就我个人而言,我使用单独的对象/上下文将错误记录到数据库中,并且这个错误处理对象与它相关联 new Context实例被注入(inject)到包装我的服务的异常处理装饰器中。如果错误记录对象无法记录到数据库,它也会写入错误日志。

    异常就是这样,异常,所以有两个Contexts此时不是问题,因为它不应该经常发生。

    关于entity-framework - 从 Entity Framework 上下文中删除失败的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17451186/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com