C# 如果';提交变更';失败,但需要其他提交?

C# 如果';提交变更';失败,但需要其他提交?,c#,.net,linq-to-sql,transactions,C#,.net,Linq To Sql,Transactions,在某些商业案例中,我的应用程序在事务内部存在错误原因。情况是这样的: static void MyFunc(DBContext context) { context.MyObjects.InsertOnSubmit(new MyObj{Id=1}); // Id - is a primary key context.MyObjects.InsertOnSubmit(new MyObj{Id=1});

在某些商业案例中,我的应用程序在事务内部存在错误原因。情况是这样的:

static void MyFunc(DBContext context)
{
    context.MyObjects.InsertOnSubmit(new MyObj{Id=1});
                                         // Id - is a primary key
    context.MyObjects.InsertOnSubmit(new MyObj{Id=1});
                                         // here I force system to fail
                                         // by trying to add record with
                                         // duplicated primary key value

    context.SubmitChanges(); // causes an error (as expected)
}

static void main()
{
    using (DBContext context = new DBContext())
    {
        try
        {
            using (TransactionScope scope = CreateTransactionScope())
            {
                MyFunc(context);

                scope.Complete();
            }
        }
        catch(Exception exc)
        {
            MyLog log = new MyLog{...valid object data... want to log error ... };
            context.MyLogs.InsertOnSubmit(log);
            context.SubmitChanges();
        }
    }
}
这里的问题是,尝试保存“日志”对象会导致尝试将以前添加的对象保存到“MyObject”表中!因此,我无法保存日志记录。。。我的“main”函数抛出一个异常

我怎样才能解决这个问题?欢迎有任何想法

(我正在使用MS SQL 2005、Linq2Sql、.NET 3.5和.NET 4.0的想法也很受欢迎!)

另外,我知道调用“scope.Rollback”可能是个好主意,但是如果我离开“using(TransactionScope scope…”,而不调用“Complete”,那么“Rollback应该自动应用…”


p.p.S.我可以创建一个新的“DBContext”对象,但我认为这是不合理的。

一般来说,DataContext将在内存中保留对从它加载或附加到它的所有对象的引用。我可能错了,但我不相信TransactionScope中的更改会回滚到“内存中”对象中


因此,错误处理程序中上下文上的SubmitChanges()将尝试重新提交对“内存中”模型的所有更改。我所知道的纠正这种情况的唯一方法是通过创建新上下文来重置“内存中”模型

事务是一种工具,用于对必须作为整体而不是部分执行的操作进行分组。由于您有一些操作可以(并且在您的情况下必须)轻松地与其他操作分离,因此使用两个单独的事务似乎更合适。

您可以在这样的上下文中回滚

public void Rollback()
{
    base.ChangeTracker.Entries().ToList().ForEach(entry => entry.State = System.Data.EntityState.Unchanged);
}

为什么创建单独的上下文不是一个合理的解决方案?如果有任何其他方法-我宁愿。。。否则-是的,这将是一个解决方案。。。问题是:我预计在将来的其他情况下,我的业务逻辑可能会在提交更改期间导致错误,但仍需要在同一调用(在同一上下文中)中进行其他更改。。。而使用上下文对我来说并不是很有吸引力。如果你想在其他数据失败的情况下写入一些数据,你有两个简单的选择:1)使用单独的上下文,2)使用单独的事务。但这不会将内存中的对象校正为当前的数据库对象,对吗?如果以后,在DbContext和该对象的生存期内,您修改了该对象上的另一个属性,那么由于其他属性仍然是脏的,它们也可以保存回数据库(取决于检测更改设置)。这不是回滚,它只是防止更改被持久化