2009-09-14 2 views
1

Я хотел бы использовать Example.Create() для запроса только по уникальным значениям экземпляра. Для этого мне нужно узнать значение уникального ключа имущества, который был установлен в файле отображения, например:Как использовать NHibernate для запроса по значениям уникального ключа

<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»?

ответ

0

Чтобы получить это, вам необходимо исследовать объект 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. И это, безусловно, можно было бы сделать более эффективным! Он также не делает никаких захватов условий ошибки (например, если вы укажете ему неправильное имя ключа или тип неподключенного типа, то он сработает).

Cheers, John

+0

Спасибо! Мне помог использовать NHibernate.Cfg.Configuration. Первоначально я думал, что могу решить эту проблему с помощью функции SessionFactory.GetClassMetadata(). – Martin