【问题标题】:Is it possible to use same ClassMap with different DB schemas in NHibernate?是否可以在 NHibernate 中使用具有不同数据库模式的相同 ClassMap?
【发布时间】:2016-03-16 16:25:18
【问题描述】:

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

现在我需要改变方法并将这两个数据库合并为一个。我计划通过为它们引入不同的模式来分离同名的表。听起来很容易。但是当我检查如何更新我的 NHibernate 映射以使它们支持一种或另一种模式时出现了问题 - 似乎映射类仅支持无参数构造函数(至少所有将映射添加到 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 个映射类,使用 System.Emit 从每个“基本”映射派生。使用在运行时生成的程序集传递给AddMappingFromAssembly 方法。

我错过了什么吗? 是否有一种简单的方法来指定使用指定 NHibernate 配置创建的所有存储库的架构

【问题讨论】:

  • 也许答案是使用约定,我从未将它们与 NHibernate 代码映射一起使用。看这里fabiomaulo.blogspot.mx/2011/07/…
  • MsSql2008Configuration :看起来像是特定于您的代码的自定义类。我猜它确实继承自 NHibernate.Cfg.Configuration,不是吗?
  • @Frédéric,你是对的。替换的代码,依赖于我们的自定义数据层和相应的纯 FluentNHibernate 配置代码。
  • 既然回答您的实际需求的内容与您的问题不符,也许您应该edit 并在其中添加一些注意事项(或者甚至改写您的问题,尤其是它的标题)。这将有助于找到这个问题和答案并对其他人有用。
  • @Frédéric,虽然答案与我的预期出人意料地不同,但我相信这个问题反映了我想要得到的东西,因此可以搜索。我稍微改写了一下,使其更笼统

标签: c# nhibernate


【解决方案1】:

与其适配所有映射,不如使用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 的性能。

【讨论】:

  • 它应该可以工作。但是你能提供一些如何通过源代码配置它的示例吗?我看到文档说它是一个 sessionFactory 设置,但 ISessionFactory 没有任何方法可以通过源代码指定模式。很奇怪……
  • 这可能是由于我们仍在使用的旧版 NHibernate。将在测试项目中尝试新的
  • 没有命名属性。它们是通过属性字典处理的。
  • 谢谢,效果很好。我们确实在 NHibernate 上有了自定义数据层,这让我很困惑
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-22
  • 1970-01-01
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
相关资源
最近更新 更多