/ / Entity Framework и SQL Server Savepoints - .net, .net-4.0, entity-Framework-4, sql-server-2008-r2, savepoints

Entity Framework и SQL Server Записни точки - .net, .net-4.0, entity-framework-4, sql-server-2008-r2, savepoints

Попитах го различен въпрос относно вложените транзакции и отговорът на въпроса ми ме образова достатъчно, за да ми помогне да осъзная, че задавам въпроса слабо. Така че тук е по-добър въпрос.

Как мога ефективно да реализирам точките за запазване на SQL Server (връзка 1, връзка 2) с DAL, изграден върху Entity Framework 4.0?

Бих искал да напиша следния код и да го накарам да работи по начин, който SAVEPOINTS на 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 за отговор № 1

Това не е доста пълен отговор, но подозирам, че нещо подобно може да тръгне по правия път. Моят проблем е, че Не съм напълно сигурен как да получа SqlTransaction, докато сте в 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);
}
}