题 Fluent NHibernate - 仅在不存在时创建数据库模式


我有一个应用程序,我使用Fluent Nhibernate来创建我的数据库。到目前为止,我每次都在重新创建数据库模式。执行此操作的代码是这样的:

public NhibernateSessionFactory(IPersistenceConfigurer config)
{
    _sessionFactory = Fluently.Configure().
        Database(config).
        Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingsPersistenceModel>()).
        ExposeConfiguration(BuildSchema).
        BuildSessionFactory();
}

private static void BuildSchema(Configuration config)
{
    // if (DbExists(config))
    //    return; 

    new SchemaExport(config).Create(false, true);
}

注意“if (DbExists(config))“这就是我想要做的。我只想在它实际上还没有存在的情况下创建模式。在下一步 - 我想更新 如果它不是最新的,它将被创建。

我该如何实现这一目标?我期待着 config.DatabaseExists(),但我看不到这样的事情。我看到了一些hacky解决方案的可能性,但是处理这个问题的典型推荐方法是什么?


34
2018-05-04 13:43


起源




答案:


你可以使用 SchemaUpdate 相反,如果模式存在,它将更新模式,如果模式不存在则创建模式:

public NhibernateSessionFactory(IPersistenceConfigurer config)
{
    _sessionFactory = Fluently.Configure().
        Database(config).
        Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingsPersistenceModel>()).
        ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true)).
        BuildSessionFactory();
}

一个警告: SchemaUpdate 不进行破坏性更新(删除表,列等)。它只会添加它们。


69
2018-05-04 14:39



太棒了!这正是我想要的。谢谢! - stiank81
完善!谢谢 - Bronek


更新 (感谢dotjoe)

Hbm2ddl只能执行模式差异,只能更新SchemaUpdate类更改的内容。然而,这个类非常简陋,因为它只需要查看当前实体以及模式的不同之处。如果已经进行了重大更改(即删除了实体或删除了链接表),它将无法解决这个问题。

在早期的项目中我们使用了hbm2ddl,但是我们已经开始使用Fluent Migrator了。我想说最好的办法是使用迁移工具,如Fluent Migrator或Migrator.NET。

http://github.com/schambers/fluentmigrator/

http://code.google.com/p/migratordotnet/


10
2018-05-04 14:36



实际上Hbm2ddl可以生成更改脚本 SchemaUpdate......但是,它并没有抓住一切,我永远不会依赖它。 - dotjoe
@dotjoe你刚才提到它没有做破坏性更新的事实?我在生产中使用SchemaUpdate,从来没有遇到任何问题。 - Gabe Moothart
@Gabe Moothart它不会捕获像列无效的更改,但我想如果从空列移动到非空列,那将被视为破坏性更改。 - dotjoe
感谢名单!将在未来继续深入研究,但目前SchemaUpdate正是我所寻找的。 - stiank81