2009-02-04 73 views
0

我的应用程序同时支持Oracle和MS SQL数据库,每个数据库都有略微不同的架构。我遇到的一个问题是在MS SQL下有一个自动递增主键的类,但在Oracle下是一个手动插入的主键。使用嵌入式资源加载NHibernate编程映射文件

眼下,这两个不同的映射类是这样的:

甲骨文:

<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"/> 

MS 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(); 

回答

2

我可能会丢失你的要害。 NHibernate在如何将映射文件提供给它时​​非常灵活。例如

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

或定制XML字符串:

cfg.AddXml(myCustomBuildXmlString); 

您也可以通过编程直接添加映射,但是这是一个有点棘手。