Domanda

Vorrei usare Example.Create () per eseguire una query solo in base ai valori univoci di un'istanza. Per fare ciò ho bisogno di scoprire il valore della proprietà chiave unica impostata nel file di mappatura, in questo modo:

  <property name="MyColumn">
    <column name="MyColumn" unique-key="MyUniqueKeyGroup"/>
  </property>

Per una migliore comprensione - ecco la parte importante del codice:

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
}

Cosa devo fare per scoprire se una proprietà appartiene al gruppo di chiavi univoche 'MyUniqueKeyGroup'?

È stato utile?

Soluzione

Dovrai sondare l'oggetto Nhibernate.Cfg.Configuration per ottenere questo. Lo avresti costruito da qualche parte per creare la tua istanza ISessionFactory. Qualcosa del genere potrebbe funzionare:

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)))
    }
}

In realtà non ho compilato questo per verificare che funzioni, quindi YMMV. E potrebbe certamente essere reso più efficiente! Inoltre, non esegue alcun trapping delle condizioni di errore (ad es. Se si assegna un nome chiave errato o un tipo di classe non mappato, si arresterà in modo anomalo).

Saluti, John

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top