Reputation: 5897
I have a simple query which updates two tables in my database
public void UpdateLogins(int userId)
{
using (var context = new storemanagerEntities())
{
user item = context.users.Where(x => x.id == userId).FirstOfDefault();
item.logins += 1;
context.SaveChanges();
account accountItem = context.accounts.Where(x => x.userId == userId).FirstOfDefault();
accountItem.logins += 1;
context.SaveChanges();
}
}
but if I but a "throw new Exception();" between them like so
context.SaveChanges();
throw new Exception();
account accountItem = context.accounts.Where(x => x.userId == userId).FirstOfDefault();
the user table is not updated but my account table has not been updated, and the database saves these changes. How can I tell my database to rollback the changes if a exception is thrown?
Thanks
Upvotes: 3
Views: 983
Reputation: 4259
Each .SaveChanges is a transaction. So you have 2.
As others pointed out enclose all in parent TransactionScope and then these 2 will became child transactions.
I.e. you'll have 1 transaction.
Or better to make just one call to .SaveChanges()
When operating with your models you should use C# references to connect models, not by ids. Sometimes that is difficult, but that is the goal of ORMs, to let you work in OO terms.
User can have an Account property and that is a connection in OO terms, not by ID. Same for Account - User property.
Order instance can have List OrderDetails property.
Look here for nice examples: EF Code First Cookbook — Recipe #4: Adding Details to a Master Entity
Upvotes: 1
Reputation: 4100
Try this :
using (TransactionScope txScope = new TransactionScope())
{
using (var context = new storemanagerEntities())
{
user item = context.users.Where(x => x.id == userId).FirstOfDefault();
item.logins += 1;
context.SaveChanges();
account accountItem = context.accounts.Where(x => x.userId == userId).FirstOfDefault();
accountItem.logins += 1;
context.SaveChanges();
}
txScope.Complete();
}
Upvotes: 4
Reputation: 33
You could try this:
The data is going to be saved to the database but not committed until the Scope.Complete() is done.
Upvotes: 0