代码之家  ›  专栏  ›  技术社区  ›  Coxy

使用嵌入式资源加载nhibernate编程映射文件

  •  0
  • Coxy  · 技术社区  · 15 年前

    我的应用程序同时支持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();
    
    1 回复  |  直到 11 年前
        1
  •  2
  •   Cristian Libardo    15 年前

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

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

    或自定义生成的XML字符串:

    cfg.AddXml(myCustomBuildXmlString);
    

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