Issue: (With Sql 2005)
So I found this much:
[TestMethod]
public void CreateUser()
{
TransactionScope transactionScope = new TransactionScope();
DataContextHandler.Context.AddToForumUser(userToTest);
DataContextHandler.Context.SaveChanges();
DataContextHandler.Context.Dispose();
}
Where DataContextHandler is just a simple singleton that exposes the context object for my entities. This seems to work just as you would think. It creates the user, saves, then rolls back when the program ends. (IE test finishes)
Problem: How do I force the transaction to rollback and kill itself so that I can query the table?
Reason: For testing purposes, I want to make sure the user:
As of right now, I can only get the transaction to rollback if the test ends AND I can't figure out how to query with the transaction up:
[TestMethod]
public void CreateUser()
{
ForumUser userToTest = new ForumUser();
TransactionScope transactionScope = new TransactionScope();
DataContextHandler.Context.AddToForumUser(userToTest);
DataContextHandler.Context.SaveChanges();
Assert.IsTrue(userToTest.UserID > 0);
var foundUser = (from user in DataContextHandler.Context.ForumUser
where user.UserID == userToTest.UserID
select user).Count(); //KABOOM Can't query since the
//transaction has the table locked.
Assert.IsTrue(foundUser == 1);
DataContextHandler.Context.Dispose();
var after = (from user in DataContextHandler.Context.ForumUser
where user.UserID == userToTest.UserID
select user).Count(); //KABOOM Can't query since the
//transaction has the table locked.
Assert.IsTrue(after == 0);
}
UPDATE This worked for rolling back and checking, but still can't query within the using section:
using(TransactionScope transactionScope = new TransactionScope())
{
DataContextHandler.Context.AddToForumUser(userToTest);
DataContextHandler.Context.SaveChanges();
Assert.IsTrue(userToTest.UserID > 0);
//Still can't query here.
}
var after = (from user in DataContextHandler.Context.ForumUser
where user.UserID == userToTest.UserID
select user).Count();
Assert.IsTrue(after == 0);
Here you will learn about the transactions in EF 6.x & EF Core. In Entity Framework, the SaveChanges () method internally creates a transaction and wraps all INSERT, UPDATE and DELETE operations under it. Multiple SaveChanges () calls, create separate transactions, perform CRUD operations and then commit each transaction.
Entity Framework will neither commit nor rollback the existing transaction when you do this, so use with care and only if you’re sure this is what you want to do. Errors in UseTransaction You will see an exception from Database.UseTransaction() if you pass a transaction when: Entity Framework already has an existing transaction
What EF does by default. In all versions of Entity Framework, whenever you execute SaveChanges() to insert, update or delete on the database the framework will wrap that operation in a transaction. This transaction lasts only long enough to execute the operation and then completes.
Entity Framework already has an existing transaction Entity Framework is already operating within a TransactionScope The connection object in the transaction passed is null. That is, the transaction is not associated with a connection – usually this is a sign that that transaction has already completed
From MSDN;
"SaveChanges operates within a transaction. SaveChanges will roll back that transaction and throw an exception if any of the dirty ObjectStateEntry objects cannot be persisted. "
So it seems that there is no need to to explicitly add your own transaction handling through TransactionScope
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With