NHibernate的纲领性映射文件加载与嵌入的资源纲领性、加载、文件、资源

2023-09-04 06:51:25 作者:细腻长发姐

我的应用程序同时支持Oracle和MS SQL数据库,与已实施了每一个稍微不同的模式。我碰到的一个问题是一类具有在MS SQL一个自动增加的主键,但甲骨文在手动插入的主键。

目前,两种不同的映射类是这样的:

甲骨文:

 <类懒惰=假NAME =EntityPropertyName表=entity_property_name>
< ID名称=ID列=id类型=的Int32未保存值= -  1>
  <生成器类=增量/>
< / ID>
<属性名=姓名一栏=名/>
 

MS SQL:

 <类懒惰=假NAME =EntityPropertyName表=entity_property_name>
< ID名称=ID列=id类型=的Int32未保存值= -  1>
  <生成器类=本土与GT;
  < /发电机>
< / ID>
<属性名=姓名一栏=名/>
 

PDF文件一键添加水印的技巧

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

  NHibernate.Cfg.Configuration CFG =新NHibernate.Cfg.Configuration();

如果(newDBType == CompanyName.AppName.Data.Enum.DatabaseType.MsSqlServer)
{
cfg.Properties [方言] =NHibernate.Dialect.MsSql2000Dialect;
cfg.Properties [connection.driver_class] =NHibernate.Driver.SqlClientDriver;
                cfg.AddFile(数据类型\\ MSSQLTypes.hbm.xml);
}
			其他
{
cfg.Properties [方言] =NHibernate.Dialect.Oracle9Dialect;
cfg.Properties [connection.driver_class] =NHibernate.Driver.OracleClientDriver;
                cfg.AddFile(数据类型\\ OracleTypes.hbm.xml);
}

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

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

cfg.AddAssembly(CompanyName.AppName.Data);

会话= cfg.BuildSessionFactory();
 

我不喜欢这一战略的事情是,虽然我现在已经在我的项目的bin目录中一些丑陋的XML文件,这需要在那里或应用程序将无法正常工作。这将是一个好多了,如果我可以嵌入不同的文件到资源就像我可以和我的主映射文件,而是选择是否加载每个文件或无法在运行时。

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

编辑: 谢谢你,克里斯蒂安!你没明白的问题,我只是不知道资源可NHibernate的加载这样。它的思考,我想这是有道理的AddAssembly方法,就必须有某种方式来列举并加载它找到的!

资源

我的解决方案,结束了:

  NHibernate.Cfg.Configuration CFG =新NHibernate.Cfg.Configuration();

如果(newDBType == CompanyName.AppName.Data.Enum.DatabaseType.MsSqlServer)
{
cfg.Properties [方言] =NHibernate.Dialect.MsSql2000Dialect;
cfg.Properties [connection.driver_class] =NHibernate.Driver.SqlClientDriver;
                cfg.AddInputStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("CompanyName.AppName.Data.DataTypes.MSSQLTypes.hbm.xml"));
}
			其他
{
cfg.Properties [方言] =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"));

会话= cfg.BuildSessionFactory();
 

解决方案

我可能会丢失你的要害。 NHibernate的是相当灵活的,你如何给它的映射文件。例如,

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

或定制的XML字符串:

  cfg.AddXml(myCustomBuildXmlString);
 

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

My application supports both Oracle and MS SQL databases, with slightly different schemas having been implemented for each. One issue I've run into is a class that has an auto-increment primary key under MS SQL, but a manually-inserted primary key under Oracle.

Right now, the two different mappings for the class look like this:

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

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

This isn't the worst thing in the world, because I can put them into different mapping files and load the correct one at runtime.

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

The thing I dislike about this strategy though is that I now have some ugly XML files in my program's bin directory, which need to be there or the application won't work. It would be a lot better if I could embed the different files into the resource like I can with my main mapping file, but choose whether to load each file or not at runtime.

Is there any way to do this, or perhaps a different way to solve the problem?

Edit: Thank you, Cristian! You did understand the question, I was just unaware that resources could be loaded by NHibernate like that. Thinking on it, I suppose it makes sense for the AddAssembly method would have to have some way to enumerate and load the resources that it finds!

My solution ended up being:

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

解决方案

I might be missing your crucial point. NHibernate is quite flexible in how you can feed it the mapping files. e.g.

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

or a custom built xml string:

cfg.AddXml(myCustomBuildXmlString);

You can also add mappings programmatically directly but that's a bit trickier.