Как использовать NHibernate для запроса по значениям уникальных ключей
-
07-07-2019 - |
Вопрос
Я хотел бы использовать example.Create() для запроса только уникальных значений экземпляра.Для этого мне нужно узнать значение свойства unique-key, которое было установлено внутри файла сопоставления, например:
<property name="MyColumn">
<column name="MyColumn" unique-key="MyUniqueKeyGroup"/>
</property>
Для лучшего понимания — вот важная часть кода:
criteria.Add(Example.Create(myObject).SetPropertySelector(new MyPropertySelector()));
[...]
public class MyPropertySelector: NHibernate.Criterion.Example.IPropertySelector
{
#region IPropertySelector Member
public bool Include(object propertyValue, string propertyName, IType type)
{
/* here is where I want to check if the property belongs
* to the unique-key group 'MyUniqueKeyGroup' and return true if so
*/
}
#endregion
}
Что мне нужно сделать, чтобы узнать, принадлежит ли свойство группе уникальных ключей MyUniqueKeyGroup?
Решение
Вам нужно будет исследовать Nhibernate.Cfg.Configuration
возражать, чтобы получить это.Вы бы сконструировали это где-нибудь, чтобы создать свой экземпляр ISessionFactory.Что-то вроде этого может сработать:
private NHibernate.Cfg.Configuration _configuration;
[...]
var selector = new MyPropertySelector<MyClass>(_configuration, "MyUniqueKeyGroup");
criteria.Add(Example.Create(myObject)
.SetPropertySelector(selector));
[...]
public class MyPropertySelector<T>: NHibernate.Criterion.Example.IPropertySelector
{
private NHibernate.Cfg.Configuration _onfiguration;
private IEnumerable<NHibernate.Mapping.Column> _keyColumns;
public MyPropertySelector(NHibernate.Cfg.Configuration cfg, string keyName)
{
_configuration = cfg;
_keyColumns = _configuration.GetClassMapping(typeof(T))
.Table
.UniqueKeyIterator
.First(key => key.Name == keyName)
.ColumnIterator);
}
public bool Include(object propertyValue, string propertyName, IType type)
{
return _configuration.GetClassMapping(typeof(T))
.Properties
.First(prop => prop.Name == propertyName)
.ColumnIterator
.Where(col => !col.IsFormula)
.Cast<NHibernate.Mapping.Column>()
.Any(col => _keyColumns.Contains(col)))
}
}
На самом деле я не компилировал это, чтобы проверить, работает ли это, поэтому YMMV.И, конечно же, его можно было бы сделать более эффективным!Он также не выполняет никакого перехвата ошибок (например,если вы дадите ему неправильное имя ключа или несопоставленный тип класса, произойдет сбой).
Ура, Джон