在我传递给Execute.WithConnection
的操作内部调用FluentMigrator的构建器方法会导致抛出空引用异常。
我要做的是选择一些数据,以便我可以在c#中操作它,因为这比在T-SQL中操作它更容易,并使用我的c#操作的结果来更新数据或插入新数据(更具体地说,我需要从存储的url字符串中选择一个查询字符串参数并将其插入其他地方)。
我看到在迁移中选择数据的唯一方法是使用Execute.WithConnection
并自己检索数据(FluentMigrator不提供用于选择数据的帮助程序),但是如果我尝试在操作中使用任何流畅的迁移器表达式我传递给Execute.WithConnection
抛出了一个空引用异常。
这是我的代码的简化版本:
[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() {}
}
调用Inser.IntoTable的行会导致从FluentMigrator\Builders\Insert\InsertExpressionRoot.cs
的第36行抛出空异常 - 此时_context变量似乎为null,但我不明白为什么会这样。 (当测试Create.Table时,例如,它发生在FluentMigrator\Builders\Create\CreateExpressionRoot.cs
的第49行)
任何帮助将不胜感激。也许对DML是否适合迁移存在分歧,我对建议持开放态度,但这种情况本周已经出现两次。现在我只是在动作中使用我的micro-ORM而不是FluentMigrator来执行插入,这确实有效,但看起来我想要做的事情应该起作用。
答案 0 :(得分:3)
当使用Execute.WithConnection表达式时,你得到的只是数据库连接和事务。
使用Execute.WithConnection创建PerformDBOperationExpression表达式。处理表达式时,处理器调用Operation属性(an example in the SqlServerProcessor),处理器没有对MigrationContext的引用。但即使它确实可以访问MigrationContext,当FluentMigrator进入处理阶段时,已经太晚了。您将尝试在表达式中处理表达式,目前还没有构建FluentMigrator来处理这种类型的嵌套。
另一种方法是在迁移上下文中使连接字符串可用,请参阅此问题:https://github.com/schambers/fluentmigrator/issues/240
这会是一种更好的方法吗?