2010-11-26 15 views
2

Ich weiß, dass diese Frage schon einmal gestellt wurde, aber ich muss noch eine Antwort finden, die tatsächlich funktioniert.TransactionScope und DataContext

Mein Problem tritt auf, wenn meine Komponententests versuchen, einen Webdienst aufzurufen, der Linq verwendet, um die Datenbank abzufragen.

Die Unit-Test ist wie so ein:

[TestInitialize] 
public void SetUp() 
{ 
    var scope = new TransactionScope(TransactionScopeOption.Required,TimeSpan.MaxValue); 
    var database = new DatabaseDataContext(); 
} 

[TestCleanup] 
public void TearDown() 
{ 
    scope.Dispose(); 
    database.Dispose(); 
} 

[TestMethod] 
public void GetCategoryList_Success() 
{ 
    // create test data 
    var result = service.GetItems(); 
} 

Die service.GetItems Methode, wie so aussieht:

try 
{ 
    using (DatabaseDataContext database = new DatabaseDataContext()) 
    { 
     var items = (from i in database.Items 
        select i).ToList<Items>(); 
     return items; 
    } 
} 
catch (Exception ex) 
{ 
    // log error 
    return null; 
} 

Wenn die Linq Abfrage auszuführen versucht, wird die folgende Ausnahme ausgelöst:

Die Operation gilt nicht für den Status der Transaktion.

Ich glaube, dies mit verschachtelten Transaktionen zu tun, aber ich brauche die Transaktion in der Testklasse offen zu halten, so dass die Testdaten tatsächlich nicht in die Datenbank gespeichert und ich kann darüber verfügen, wenn der Test Lauf.

Auch mein Hosting befindet sich in einer gemeinsam genutzten Instanz, daher kann ich keine Änderungen direkt am Server vornehmen.

Gibt es eine Möglichkeit, dies so zu machen, wie es ist, oder gibt es alternativ eine Alternative zur Verwendung von TransactionScope in diesem Kontext?

Antwort

0

Sie versuchen, innerhalb eines TransactionScope zwei Verbindungen zu derselben Datenbank zu erstellen - eine Verbindung für den Testprozess und eine weitere für den Web-Service-Prozess. Dies funktioniert nicht, da in der Datenbank Transformationen aus verschiedenen Prozessen offensichtlich nicht verschachtelt werden können.

Sie sollten hier Ihren Ansatz zum Testen ändern. Lies Jan's Antwort.

Um dieses Problem zu umgehen, können Sie Ihren Web-Service veranlassen, die Transaktion zu verwalten. Eine Methode, zum Beispiel BeginGlobalTran, sollte ein globales Transaction (oder TransactionScope) -Objekt für den Webservice (in der Eigenschaft gespeichert) erstellen, alle anderen Methoden sollten dieses Objekt verwenden (alle anderen Transaktionen sind also in der 'globalen' Transaktion verschachtelt), eine andere Methode sagen, RollbackGlobalTran sollte diese "globale" Transaktion Rollback.
Dies ist eine Umgehung und es kann einige unerwartete Nebenwirkungen (z. B. ein Fehler in der Methode wird die 'globale' Transaktion nicht zulässig, so dass Sie es neu starten müssen, um weitere Fehler zu vermeiden) verursachen.

Verwandte Themen