Massive ORM - транзакция за несколькими столами

Я смотрел на Massive ORM. Не забывайте, просто глядя, я еще не занимался кодированием.

Меня интересуют возможности сохранения данных транзакций. Я видел, что можно сохранить 20 строк в одной таблице за одну транзакцию. Но что происходит, когда я хочу сохранить Заказ и его Строки в одной Транзакции? Это возможно, как?

2 ответа

Решение

Объявление метода Massive Save() выглядит следующим образом:

Save(params object[] things)

... и внутри он выполняет цикл foreach для каждого переданного объекта и сохраняет его в базе данных в одной транзакции, поэтому он уже выполняет то, что вы хотите.

Теперь, если вы хотите контролировать транзакцию самостоятельно, тогда давайте начнем.

Прежде всего, почти каждый метод в Massive помечен как виртуальный, поэтому мы можем переопределить любые методы в производном классе, поэтому мы это и сделаем. Теперь все вызовы Save() в конечном итоге проходят через метод Execute(), который принимает IEnumerable из DbCommand, поэтому мы переопределим этот метод в нашем производном классе.

Вот наш производный класс:

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;
    }
}

Так что теперь нам просто нужно предоставить наши собственные IDbConnection и IDbTransaction для нашего нового класса ExtendedDynamicModel, например, так:

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();
        }
    }
}

Так что теперь у нас есть полный контроль над фиксацией или откатом транзакции, если нам нужно.

Ссылка на исходный код Massive для справки: https://github.com/robconery/massive/

Я просматривал это некоторое время, и вот мое мнение об этом, используя только транзакцию Massive по умолчанию: я использую в своих интересах

table.Execute(IEnumerable<DbCommands>)

вот некоторый примерный пример кода

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!

}
Другие вопросы по тегам