Domanda

I've been looking at Massive ORM. Don't forget, just looking, I didn't do any coding yet.

I'm interested of the possibilities to save data transactional. I've seen it's possible to save, 20 lines in the same table in one transaction. But what happens when I want to save an Order and it's Orderlines in a single Transaction? Is that possible, how?

È stato utile?

Soluzione

Massive's Save() method declaration looks like this:

Save(params object[] things)

...and internally it does a foreach loop over each object passed in and saves it to the database in a single transaction so it already does what you want it to do.

Now if you would like to control the transaction yourself, then let's get started.

First of all, almost every method in Massive is marked virtual, therefore we can override any methods in a derived class so that's what we'll do. Now all calls to Save() eventually go through an Execute() method that takes an IEnumerable of DbCommand's so we'll override that method in our derived class.

Here's is our derived class:

public class ExtendedDynamicModel : DynamicModel
{
    // Lets add two properties that we will reference in our overridden Execute method
    public System.Data.IDbConnection Connection;
    public System.Data.IDbTransaction Transaction;

    public ExtendedDynamicModel( string connectionStringName, string tableName = "",
                                 string primaryKeyField = "", string descriptorField = "" )
        : base( connectionStringName, tableName, primaryKeyField, descriptorField )
    {
    }

    // Lets override the Execute method and if we've supplied a Connection, then let's
    // using our own custom implementation otherwise use Massive's default implementation.
    public override int Execute( IEnumerable<System.Data.Common.DbCommand> commands )
    {
        if ( Connection == null ) return base.Execute( commands );

        var result = 0;

        foreach ( var cmd in commands as IEnumerable<System.Data.IDbCommand> )
        {
            cmd.Connection = Connection;
            cmd.Transaction = Transaction;
            result += cmd.ExecuteNonQuery();
        }

        return result;
    }
}

So now we just need to supply our own IDbConnection and IDbTransaction to our new ExtendedDynamicModel class like so:

var database = new ExtendedDynamicModel( "YourConnectionString" );

using ( var connection = database.Connection = database.OpenConnection() )
{
    using ( var tx = database.Transaction = connection.BeginTransaction() )
    {
        // Do your saving here

        if ( true )
        {
            tx.Commit();
        }
        else
        {
            tx.Rollback();
        }
    }
}

So now we have complete control over committing or rolling back the transaction if we need to.

Link to Massive's source code for reference: https://github.com/robconery/massive/

Altri suggerimenti

I have been looking over this one for a while and here is my take on it just using Massive's default transaction: I am taking advantage of

table.Execute(IEnumerable<DbCommands>)

here's some hypothetical sample code

private bool BigSave(int id)
{
    var saveList = new List<DbCommand>();

    var tblO = new Order();
    var order = tblO.Single(key: id);  /* get the order record */
    order.OrderDate = DateTime.Today;  /* update order's fields */

    /* more updates if needed */
    saveList.Add(tblO.CreateUpdateCommand(order, id)); /* add Order to command list */

    /* now delete some existing order lines */
    var lines2Delete = "25, 31, 33" // let's assume some comma separated Ids

    var tblL = new OrderLines();

    saveList.Add(tblL.CreateDeleteCommand(string.Format("WHERE Id IN ({0})", lines2Delete)));

    /* now add some new Orderlines */
    /* for this usually I create a List<dynamic> */
    var newLines = new List<dynamic>(); /* add your objects to this list */

    /* now add each of those to the List of Save commands using a foreach loop */
    /* or LINQ:
        saveList.AddRange(newLines.Select(o => tblL.CreateInsertCommand(o).Cast<DbCommand>());
    */
    tblO.Execute(saveList); //boom: save everything in a Transaction!

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top