0

我问了一个关于嵌套事务的different question,对我的问题的回答足以让我意识到我提出的问题很差。所以这里有一个更好的问题。实体框架和SQL Server保存点

我怎样才能有效地与在实体框架4.0内置了DAL实现SQL Server的保存点(link 1link 2)?

我还想写下面的代码,并把它的工作方式是SQL Server的保存点

public void Bar() 
{ 
    using (var ts = new TransactionScope()) 
    { 
    var ctx = new Context(); 
    DoSomeStuff(ctx); 

    bool isSuccessful; 

    using (var spA = new SavePoint("A")) // <-- this object doesn't really exist, I don't think 
    { 
     isSuccessful = DoSomeOtherStuff(ctx); 
     if (isSuccessful) 
     spA.Complete(); // else rollback bo prior to the beginning of this using block 
    } 

    Log(ctx, isSuccessful); 

    ts.Complete(); 
    } 
} 

是否有这样的方式做任何事情,甚至接近类似这样,还是其他什么东西,玩很好地与EF4? (我们使用自定义的自定义POCO实体)

回答

0

这不是一个完整的答案,但我怀疑像这样的东西可能会走向正确的道路。我的问题是I'm not entirely sure how to get a SqlTransaction while in a TransactionScope

/// <summary> 
/// Makes a code block transactional in a way that can be partially rolled-back. This class cannot be inherited. 
/// </summary> 
/// <remarks> 
/// This class makes use of SQL Server's SAVEPOINT feature, and requires an existing transaction. 
/// If using TransactionScope, utilize the DependentTransaction class to obtain the current Transaction that this class requires. 
/// </remarks> 
public sealed class TransactionSavePoint : IDisposable 
{ 
    public bool IsComplete { get; protected set; } 
    internal SqlTransaction Transaction { get; set; } 
    internal string SavePointName { get; set; } 

    private readonly List<ConnectionState> _validConnectionStates = new List<ConnectionState> 
                     { 
                      ConnectionState.Open 
                     }; 

    public TransactionSavePoint(SqlTransaction transaction, string savePointName) 
    { 
     IsComplete = false; 
     Transaction = transaction; 
     SavePointName = savePointName; 

     if (!_validConnectionStates.Contains(Transaction.Connection.State)) 
     { 
      throw new ApplicationException("Invalid connection state: " + Transaction.Connection.State); 
     } 

     Transaction.Save(SavePointName); 
    } 

    /// <summary> 
    /// Indicates that all operations within the savepoint are completed successfully. 
    /// </summary> 
    public void Complete() 
    { 
     IsComplete = true; 
    } 

    /// <summary> 
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 
    /// </summary> 
    public void Dispose() 
    { 
     if (!IsComplete) 
     { 
      Transaction.Rollback(SavePointName); 
     } 
    } 
} 

这将消耗正因为如此,非常类似于一个TransactionScope:

SqlTransaction myTransaction = Foo(); 

using (var tsp = new TransactionSavePoint(myTransaction , "SavePointName")) 
{ 
    try 
    { 
    DoStuff(); 
    tsp.Complete 
    } 
    catch (Exception err) 
    { 
    LogError(err); 
    } 
} 
+0

我这标志着作为回答,因为这是我已经能够找到最好的。 – Jaxidian