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