是否可以在NHibernate中使用具有不同数据库模式的相同ClassMap?

时间:2016-03-16 16:25:18

标签: c# nhibernate

目前我有两个相同结构的数据库(一个用于临时更改,另一个用于实时更改)。我使用相同的NHibernate实体,映射和存储库来访问这两个数据库。创建Session时仅更改连接字符串。

现在我需要改变方法并将这两个DB合并为一个。我计划通过为它们引入不同的模式来分离同名的表。听起来很容易。但是当我检查如何更新我的NHibernate映射以便它们支持一个模式或另一个模式时出现问题 - 似乎map类仅支持无参数构造函数(至少所有向NHibernate配置添加映射的方法都没有假设任何构造函数参数)。

以下是一些示例代码,用于演示我希望实现的目标:

public class MyEntityMap : ClassMap<MyEntity>
{
    public MyEntityMap ()
    {
        Table("MyEntities");
        Schema("a");    //I can specify schema as a constant here, but I need it to be variable: constructor either parameter or changable in other way
        Id(x => x.Id, "Id");
        Map(x => x.Name, "Name").Length(100);
    }
}

创建NHibernate配置时,有以下选项可以为其添加映射(三个方法调用仅针对选项显示,我目前使用单个调用AddFromAssemblyOf):

Fluently.Configure()
        .Database(MsSqlConfiguration.MsSql2008.ConnectionString("MyConnectionString"))
        .Mappings(m => m.FluentMappings.AddFromAssembly(typeof (MyEntityMap).Assembly))
        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<MyEntityMap>())
        .Mappings(m => m.FluentMappings.Add<MyEntityMap>)

显然,这两个选项都不支持ClassMap派生类的参数化构造函数,我也不知道如何同时为所有映射指定架构。

我看到的解决方案(但似乎有点矫枉过正):

  1. 从每个映射类手动创建2个派生类,并将它们放在不同的程序集中。这样每个类都为模式常量提供它的值。
  2. 自动生成2个映射类,派生自各个基地&#39;使用System.Emit进行映射。使用在运行时生成的程序集传递给AddMappingFromAssembly方法。
  3. 我错过了什么吗? 是否有一种简单的方法可以指定使用指定的NHibernate配置创建的所有存储库的哪个架构

1 个答案:

答案 0 :(得分:2)

为什么不使用default_schema配置参数?

,而不是调整所有映射

或者我错过了导致这种全球转换不适合您的情况的事情?

当然,这需要在映射中停止指定在每个必须切换模式的表上使用哪个模式。

要按代码配置此设置,您可以通过以下方式添加:

var configuration = new NHibernate.Cfg.Configuration();
...
configuration.AddProperties(
    new Dictionary<string, string>
    {
        { NHibernate.Cfg.Environment.DefaultSchema, "yourDbName.yourSchema" }
    });
...
var sessionFactory = configuration.BuildSessionFactory();

或者设置:

configuration.Properties[NHibernate.Cfg.Environment.DefaultSchema] =
    "yourDbName.yourSchema";

指定数据库名称是可选的,并非所有数据库都支持,但可以提高SQL-Server的性能。