在SaveChanges失败后调用SaveChanges

时间:2016-01-12 06:27:56

标签: entity-framework inversion-of-control

我有以下测试代码:

try
{
    Product product = productService.GetProductById(1502);
    product.ProductName = "TEST PRODUCT NAME";

    throw new ArgumentException("");

    //Do some other DB updates

    //Call SaveChanges
    productService.SaveChanges();
}   
catch(Exception ex)
{
    logService.InsertLog(LogTypeEnum.Error, "test", ex);
    logService.SaveChanges();
}

问题是我的服务每个请求共享一个上下文(使用StructureMaps HttpContextScoped)。因此,当发生故障并且我调用logService.SaveChanges时,它会保存产品的新名称。但是我失去了原子性,因为"其他数据库更新"不会保存到DB。实现这个的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

对于每个请求的上下文,这总是一个问题。在一个大型项目中,我也开始使用上下文每个请求,但由于这样的问题已逐渐删除它。

我建议你在不调用SaveChanges的情况下确定你可能需要写入数据库的场景 - 如果它只限于这个日志服务那么你可能应该重新实现它而不依赖于上下文?或者,您应该能够指定一种使用自己的上下文创建日志服务的自定义方法(即不仅仅是由构造函数注入一个)。

我不熟悉Structuremap语法,所以这里来自Autofac会做同样的事情......

builder.RegisterType<MyContext>().InstancePerRequest();  // As you have already
builder
    .Register(c => new LogService(new MyContext())
    .As<ILogService>().InstancePerRequest();

这将使用显式创建的上下文构建LogService,而不是在我正常注册的情况下注入的每个请求实例。