0

我的应用程序同时支持 Oracle 和 MS SQL 数据库,它们实现的架构略有不同。我遇到的一个问题是一个在 MS SQL 下具有自动增量主键的类,但在 Oracle 下具有手动插入的主键。

现在,该类的两个不同映射如下所示:

甲骨文:

<class lazy="false" name="EntityPropertyName" table="entity_property_name" >
<id name="ID" column="id" type="Int32" unsaved-value="-1">
  <generator class="increment" />
</id>
<property name="Name" column="name"/>

微软 SQL:

<class lazy="false" name="EntityPropertyName" table="entity_property_name" >
<id name="ID" column="id" type="Int32" unsaved-value="-1">
  <generator class="native">
  </generator>
</id>
<property name="Name" column="name"/>

这不是世界上最糟糕的事情,因为我可以将它们放入不同的映射文件并在运行时加载正确的映射文件。

NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();

            if (newDBType == CompanyName.AppName.Data.Enum.DatabaseType.MsSqlServer)
            {
                cfg.Properties["dialect"] = "NHibernate.Dialect.MsSql2000Dialect";
                cfg.Properties["connection.driver_class"] = "NHibernate.Driver.SqlClientDriver";
                cfg.AddFile("DataTypes\\MSSQLTypes.hbm.xml");
            }
            else
            {
                cfg.Properties["dialect"] = "NHibernate.Dialect.Oracle9Dialect";
                cfg.Properties["connection.driver_class"] = "NHibernate.Driver.OracleClientDriver";
                cfg.AddFile("DataTypes\\OracleTypes.hbm.xml");
            }

            cfg.Properties["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider";

            cfg.Properties["connection.connection_string"] = connectionString;

            cfg.AddAssembly("CompanyName.AppName.Data");

            Sessions = cfg.BuildSessionFactory();

不过,我不喜欢这种策略的一点是,我现在在程序的 bin 目录中有一些丑陋的 XML 文件,这些文件必须存在,否则应用程序将无法工作。如果我可以像使用主映射文件一样将不同的文件嵌入到资源中会更好,但选择是否在运行时加载每个文件。

有没有办法做到这一点,或者可能有不同的方法来解决这个问题?


编辑:谢谢你,克里斯蒂安!您确实理解了这个问题,我只是不知道 NHibernate 可以像那样加载资源。考虑一下,我认为 AddAssembly 方法必须有某种方法来枚举和加载它找到的资源是有意义的!

我的解决方案最终是:

NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration();

            if (newDBType == CompanyName.AppName.Data.Enum.DatabaseType.MsSqlServer)
            {
                cfg.Properties["dialect"] = "NHibernate.Dialect.MsSql2000Dialect";
                cfg.Properties["connection.driver_class"] = "NHibernate.Driver.SqlClientDriver";
                cfg.AddInputStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("CompanyName.AppName.Data.DataTypes.MSSQLTypes.hbm.xml"));
            }
            else
            {
                cfg.Properties["dialect"] = "NHibernate.Dialect.Oracle9Dialect";
                cfg.Properties["connection.driver_class"] = "NHibernate.Driver.OracleClientDriver";
                cfg.AddInputStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("CompanyName.AppName.Data.DataTypes.OracleTypes.hbm.xml"));
            }

            cfg.Properties["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider";

            cfg.Properties["connection.connection_string"] = connectionString;

            cfg.AddInputStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("CompanyName.AppName.Data.DataTypes.Types.hbm.xml"));

            Sessions = cfg.BuildSessionFactory();
4

1 回答 1

2

我可能错过了你的关键点。NHibernate 在如何向它提供映射文件方面非常灵活。例如

cfg.AddInputStream(assembly.GetManifestResourceStream("MyNamespace.MyEmbeddedresource.hbm.xml"));

或自定义构建的 xml 字符串:

cfg.AddXml(myCustomBuildXmlString);

您也可以直接以编程方式添加映射,但这有点棘手。

于 2009-02-04T01:04:53.023 回答