7

Calling FluentMigrator's builder methods while inside the action that I pass to Execute.WithConnection causes a null reference exception to be thrown.

What I am trying to do is select some data so that I may manipulate it in c#, as that is easier than manipulating it in T-SQL, and use the result of my c# operations to update the data or insert new data (to be more specific, I need to pick one query string parameter out of a stored url string and insert it somewhere else).

The only way I see to select data within a migration is to use Execute.WithConnection and retrieve the data myself (FluentMigrator provides no helpers for selecting data), but if I try to use any fluent migrator expression in the action I pass to Execute.WithConnection a null reference exception is thrown.

Here is a boiled down version of my code:

[Migration(1)]
public class MyMigration : Migration 
{
  public void Up() 
  {
    Execute.WithConnection(CustomDml);
  }

  public void CustomDml(IDbConnection conn, IDbTransaction tran)
  {
    var db = new NPoco.Database(conn).SetTransaction(tran); // NPoco is a micro-ORM, a fork of PetaPoco
    var records = db.Fetch<Record>("-- some sql"); // this is immediately evaluated, no reader is left open
    foreach (var r in records) {
      var newValue = Manipulate(r.OriginalValue);
      Insert.IntoTable("NewRecords").Row(new { OriginalValueId = r.Id, NewValue = newValue }); // <-- this line causes the exception
    }
  }

  public void Down() {}
}

The line that calls Inser.IntoTable causes a null exception to be thrown from line 36 of FluentMigrator\Builders\Insert\InsertExpressionRoot.cs - it appears that the _context variable may be null at this point but I do not understand why this is. (when testing Create.Table, e.g., it occurs on line 49 of FluentMigrator\Builders\Create\CreateExpressionRoot.cs)

Any help would be appreciated. Perhaps there is disagreement on whether DML is appropriate in a migration, and I am open to suggestions, but this scenario has come up twice this week alone. For now I am simply performing the insert using my micro-ORM within the action rather than FluentMigrator and that does work, but it seems like what I am trying to do should work.

4

1 に答える 1

4

Execute.WithConnection式を使用する場合、取得するのはdb接続とトランザクションだけです。

Execute.WithConnectionを使用すると、 PerformDBOperationExpression式が作成されます。式を処理するとき、プロセッサはOperationプロパティ(SqlServerProcessorの例)を呼び出しますが、プロセッサにはMigrationContextへの参照がありません。ただし、MigrationContextにアクセスできたとしても、FluentMigratorが処理段階に達したときは、すでに手遅れになっています。式内の式を処理しようとしていることになりますが、現時点では、FluentMigratorはそのタイプのネストを処理するように構築されていません。

別の方法は、移行コンテキストで接続文字列を使用できるようにすることです。この問題を参照してください:https ://github.com/schambers/fluentmigrator/issues/240

それはより良いアプローチでしょうか?

于 2013-04-03T21:19:46.553 に答える