NHibernate - 如何在运行时更改模式?

时间:2009-10-29 21:35:51

标签: nhibernate dynamic schema

我正在使用NHibernate连接到DB2服务器上的ERP数据库。我们有一个测试模式和一个生产模式。两个模式下面都有相同的表结构。对于测试,我想使用相同的映射类,但在需要时将NHibernate指向测试环境,然后在生产时返回。请记住,我们有许多生产模式,每个生产模式都有一个等效的测试模式。

我知道我的XML映射文件里面有一个架构属性,但由于它是XML格式,因此我不能通过编译器指令更改它,也不能根据配置文件更改架构属性。

有什么想法吗?

谢谢。

5 个答案:

答案 0 :(得分:1)

无需在映射中指定架构:有一个名为default_schema的SessionFactory级别设置。但是,您无法在运行时更改它,因为NHibernate预生成和/或缓存SQL查询,包括模式部分。

答案 1 :(得分:1)

为了得到我想要的东西,我不得不使用NHibernate.Mapping.Attributes。

[NHibernate.Mapping.Attributes.Class(0,Table =“MyTable”,Schema = MySchemaConfiguration.MySchema)]

通过这种方式,我可以创建一个像MySchemaConfiguration这样的类,并在其中包含一个属性,如MySchema。我可以通过编译器指令设置属性的值,也可以通过配置文件获取。这样我只需要在一个地方更改模式,它将反映在所有其他映射中。

答案 2 :(得分:1)

我找到了以下实际修复问题的链接。

How to set database schema for namespace in nhibernate

示例代码可能是

cfg.ClassMappings.Where(cm => cm.Table.Schema == "SchemaName")
    .ForEach(cm => cm.Table.Schema = "AnotherSchemaName");

这应该在您初始化自己的数据服务类之前发生。

@Brian,我试过NHibernate.Mapping.Attributes,你放在里面的属性值应该是一个常量。因此在运行时无法更新。你怎么能用配置文件中的参数值设置属性的值?

答案 3 :(得分:1)

修复HBM XML资源的代码。

    // This is how you get all the hbm resource names.
    private static IList<string> GetAllHbmXmlResourceNames(Assembly assembly)
    {
        var result = new List<string>();

        foreach (var resource in assembly.GetManifestResourceNames())
        {
            if (resource.EndsWith(".hbm.xml"))
            {
                result.Add(resource);
            }
        }

        return result;
    }
    // This is how you get the stream for each resource.
    Assembly.Load(assembly).GetManifestResourceStream(name)
    // What you need to do next is to fix schema name in this stream
    // Replacing schema name.
    private Stream FixSchemaNameInStream(Stream stream)
    {
        StreamReader strStream = new StreamReader(stream);
        string strCfg = strStream.ReadToEnd();
        strCfg = strCfg.Replace(string.Format("schema=\"{0}\"" , originalSchemaName), string.Format("schema=\"{0}\"" , newSchemaName));

        return new MemoryStream(Encoding.ASCII.GetBytes(strCfg));
    }

答案 4 :(得分:-1)