Как указано в ответе на вопрос, на который я ссылался в моем комментарии, вы не можете изменить его после создания SessionFactory.Поэтому единственный вариант, который у вас есть, - хранить второй экземпляр SessionFactory (предпочтительно также как Singleton).Это не должно быть создано одновременно с первым.Вы можете создать его, когда это необходимо, но так как создание довольно дорого, рекомендуется создать его один раз и сохранить.
Однако, если вам действительно нужно это только для массовой вставки, которая происходит только один или два раза во время выполнения приложения, то вы также можете избавиться от нее после операции.
Этобыла теория, теперь к практической части.Самый простой способ - получить копию файла Entity.hbm.xml, в котором вы просто измените атрибут генератора.Для создания SessionFactory вам необходимо предоставить параметр (возможно, Enum), чтобы вы могли решить, какие файлы .hbm.xml использовать, а какие игнорировать.
Я предлагаю назвать hbm-файл по умолчанию Entity.Default.hbm.xml и модифицированный Entity.Special.hbm.xml.Все остальные файлы hbm могут сохранять свои имена.
Вот модифицированная версия метода, который я использую для создания SessionFacory.(Я помещаю здесь bool в качестве параметра, но в своем коде я использую Enum.)
private ISessionFactory BuildSessionFactory(bool useSpecialHbmFiles)
{
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 (!useSpecialHbmFiles)
{
// we want that file for this SessionFactory
addFile = true;
}
}
else if (hbmFile.ToLower().EndsWith(".special.hbm.xml"))
{
if (useSpecialHbmFiles)
{
// we want that file for this SessionFactory
addFile = true;
}
}
else
{
// neither default nor special -> 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;
}
Редактировать:
Если вы хотите изменить только класс генератораво время выполнения вы можете изменить конфигурацию перед сборкой SessionFactory следующим образом:
// get the mapping's Key property
NHibernate.Mapping.SimpleValue keyValue =
config.GetClassMapping(typeof(MyEntity)).Key as NHibernate.Mapping.SimpleValue;
if (keyValue != null)
{
// set GeneratorStrategy (the same string you would put in generator class="..." in the hbm file)
keyValue.IdentifierGeneratorStrategy = "assigned";
}
Теперь вы можете передать параметр в свой метод CreateSessionFactory () и изменить конфигурацию.Вам все еще понадобится второй SessionFactory.Вы не можете изменить существующий.
Редактировать 2 (отключение Many-To-One):
Чтобы отключить свойство NOT-NULL в отображении для many-toодин-один свойства, попробуйте следующее:
NHibernate.Mapping.PersistentClass mapping = config.GetClassMapping(typeof(MyEntity));
foreach (NHibernate.Mapping.Property prop in mapping.PropertyIterator)
{
if (prop.Value is NHibernate.Mapping.ManyToOne)
{
prop.IsOptional = true;
}
}
Конечно, это будет работать, только если столбец внешнего ключа в БД допускает значения NULL.