Вы можете иметь два файла сопоставления для одного и того же класса домена - если вам нужен только один во время выполнения вашего кода (что, как я полагаю, будет неудобно работать с двумя разными базами данных одновременно с одним и тем же таблицы и доменные классы). Перед созданием SessionFactory вы можете отфильтровать файлы hbm и выбрать только те, которые вам нужны, в зависимости от параметра.
Вам потребуется файл сопоставления для Oracle и еще один файл для остальных, например MyEntity.oracle.hbm.xml
и MyEntity.default.hbm.xml
. Для тех классов, которые в обоих случаях одинаковы, вы просто оставляете их такими, как они есть, например MyCommonEntity.hbm.xml
.
Вот немного измененный пример кода, который я использую в нашем проекте. (Я разместил другую версию этого в другом вопросе здесь на SO: Динамически изменить генератор идентификаторов на «назначенный» в отображении класса NHibernate )
private ISessionFactory BuildSessionFactory(bool useOracleMapping)
{
Configuration config = new Configuration();
config.SetProperty(NHibernate.Cfg.Environment.ConnectionProvider, "...");
config.SetProperty(NHibernate.Cfg.Environment.Dialect, "...");
config.SetProperty(NHibernate.Cfg.Environment.ConnectionDriver, "...");
config.SetProperty(NHibernate.Cfg.Environment.ConnectionString, "...");
config.SetProperty(NHibernate.Cfg.Environment.Isolation, "Serializable");
config.SetProperty(NHibernate.Cfg.Environment.ProxyFactoryFactoryClass, "...");
config.SetProperty(NHibernate.Cfg.Environment.ShowSql, "true");
config.SetProperty(NHibernate.Cfg.Environment.Hbm2ddlKeyWords, "none");
// filter hbm Files
// Set reference to entity assembly
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(typeof(MyEntity));
// get Resource-files
string[] resources = assembly.GetManifestResourceNames();
// scan through all the hbm files and filter them according to the parameter
foreach (string hbmFile in resources)
{
// This filtering here could probably be done simpler, but this is easy to understand
bool addFile = false;
// ignore any file that does not end with .hbm.xml
if (hbmFile.EndsWith(".hbm.xml"))
{
if (hbmFile.ToLower().EndsWith(".default.hbm.xml"))
{
if (!useOracleMapping)
{
// we want that file for this SessionFactory
addFile = true;
}
}
else if (hbmFile.ToLower().EndsWith(".oracle.hbm.xml"))
{
if (useOracleMapping)
{
// we want that file for this SessionFactory
addFile = true;
}
}
else
{
// neither default nor oracle -> we want that file no matter what
addFile = true;
}
if (addFile)
{
using (System.IO.StreamReader sr = new System.IO.StreamReader(assembly.GetManifestResourceStream(hbmFile)))
{
string resourceContent = sr.ReadToEnd();
config.AddXmlString(resourceContent);
}
}
}
}
// create Sessionfactory with the files we filtered
ISessionFactory sessionFactory = config.BuildSessionFactory();
return sessionFactory;
}
Изменить:
Предполагая, что вы всегда можете получить доступ к знаниям, работаете ли вы в Oracle или в другом режиме, я бы обернул метод GetTop_AddressById()
и сделал бы что-то вроде следующего:
public Top_Address GetTop_AddressById(IDComposite_TopAddress id)
{
if (!oracle)
{
return session.CreateCriteria(DB, typeof(Top_Address))
.Add(Restrictions.Eq("ID.TnrAddress", addressID))
.Add(Restrictions.Eq("ID.TopIdentity.tnrId", tnrID))
.Add(Restrictions.Eq("AddressType", 'R')) .UniqueResult<Top_Address>();
}
else
{
return session.CreateCriteria(DB, typeof(Top_Address))
.Add(Restrictions.Eq("TnrAddress", addressID))
.Add(Restrictions.Eq("AddressType", 'R')) .UniqueResult<Top_Address>();
}
}
Это может быть не красиво, но, думаю, хуже иметь два класса для одной цели. Вам понадобится подобная обертка для всех CRUD-операций, которые используют id. Конечно, вам также понадобится свойство TnrAddress
в классе вашего домена.