Мое приложение поддерживает базы данных Oracle и MS SQL, причем для каждой из них реализованы несколько разные схемы. Одна проблема, с которой я столкнулся, - это класс, который имеет первичный ключ с автоинкрементом в MS SQL, но вставленный вручную первичный ключ в Oracle.
Прямо сейчас два разных отображения для класса выглядят так:
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"/>
Это не самая плохая вещь в мире, потому что я могу поместить их в разные файлы сопоставления и загрузить правильный во время выполнения.
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();
Что мне не нравится в этой стратегии, так это то, что у меня теперь есть несколько уродливых файлов XML в каталоге bin моей программы, которые должны быть там, иначе приложение не будет работать. Было бы намного лучше, если бы я мог встраивать различные файлы в ресурс, как я могу, с помощью моего основного файла сопоставления, но выбирать, загружать ли каждый файл или нет во время выполнения.
Есть ли способ сделать это, или, возможно, другой способ решения проблемы?
Edit:
Спасибо, Кристиан! Вы поняли вопрос, я просто не знал, что 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();