Entity Framework: Using transactions and rollbacks… Possible?

后端 未结 3 1726
天命终不由人
天命终不由人 2020-12-13 15:08

Issue: (With Sql 2005)

  • How can I query the database while the transaction is up? (Since it locks the table)
  • How can cause a t
相关标签:
3条回答
  • 2020-12-13 15:30

    I have been able to solve very similar problem using this code fragment:

    var connection = new EntityConnection("name=MyEntities");
    connection.Open();
    var tran = connection.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted);
    
    try
    {
        var dataContext = new MyEntities(connection);
    
        //CRUD operation1
    
        //CRUD operation2
    
        //CRUD operation3 ...
    
        Assert.AreEqual(expected, actual);
    }
    catch
    {
        throw;
    }
    finally
    {
        tran.Rollback();
        connection.Close();
    }
    

    Where MyEntities is the EF DataModel. The crucial part is the setting of the transaction: System.Data.IsolationLevel.ReadUncommitted.
    Using this isolation level SQL queries can read you changes done inside the transaction. Also you need to explicitly create a connection as I do on the first and second line. I couldn't make it work using TransactionScope unfortunately.

    0 讨论(0)
  • 2020-12-13 15:31

    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.

    0 讨论(0)
  • 2020-12-13 15:32

    In my case I delete all records from a Table through plain SQL since EF doesn't provide a functionality for this. After that I add some new entities - but when it fails, the table shouldn't be empty. The use of MSDTC (TransactionScope) seems not possible for me. I reduced the transaction to the DB:

    My code:

    using (var transaction = context.Connection.BeginTransaction())
    {
          // delete all
          base.DeleteAll<TESTEntity>(context);
    
          // add all
          foreach (var item in items)
          {
               context.TESTEntity.AddObject(item);
          }
    
          try
          {
               context.SaveChanges();
               transaction.Commit();
               return true;
          }
          catch (Exception ex)
          {
               Logger.Write("Error in Save: " + ex, "Error");
               transaction.Rollback();
               return false;
          }
    }
    

    And here the helper functions

        protected void DeleteAll<TEntity>(ObjectContext context) where TEntity : class
        {
            string tableName = GetTableName<TEntity>(context);
            int rc = context.ExecuteStoreCommand(string.Format(CultureInfo.InvariantCulture, "DELETE FROM {0}", tableName));
        }
    
        protected string GetTableName<TEntity>(ObjectContext context) where TEntity : class
        {
            string snippet = "FROM [dbo].[";
    
            string sql = context.CreateObjectSet<TEntity>().ToTraceString();
            string sqlFirstPart = sql.Substring(sql.IndexOf(snippet) + snippet.Length);
            string tableName = sqlFirstPart.Substring(0, sqlFirstPart.IndexOf("]"));
            return tableName;
        }
    
    0 讨论(0)
提交回复
热议问题