C# 如何使用NHibernate按唯一键值进行查询

C# 如何使用NHibernate按唯一键值进行查询,c#,.net,nhibernate,unique-key,C#,.net,Nhibernate,Unique Key,我想使用Example.Create()仅通过实例的唯一值进行查询。为此,我需要找出映射文件中设置的unique key属性的值,如下所示: <property name="MyColumn"> <column name="MyColumn" unique-key="MyUniqueKeyGroup"/> </property> 我需要做什么,才能确定某个属性是否属于唯一的密钥组“MyUniqueKeyGroup”?您需要探测Nhiberna

我想使用Example.Create()仅通过实例的唯一值进行查询。为此,我需要找出映射文件中设置的unique key属性的值,如下所示:

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

我需要做什么,才能确定某个属性是否属于唯一的密钥组“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)))
    }
}
private NHibernate.Cfg.Configuration\u配置;
[...]
var选择器=新的MyPropertySelector(_配置,“MyUniqueKeyGroup”);
criteria.Add(示例.Create(myObject))
.SetPropertySelector(选择器));
[...]
公共类MyPropertySelector:NHibernate.criteria.Example.IPropertySelector
{
私有NHibernate.Cfg.Configuration\u配置;
私有IEnumerable\u键列;
公共MyPropertySelector(NHibernate.Cfg.Configuration Cfg,字符串键名)
{
_配置=cfg;
_keyColumns=_configuration.GetClassMapping(typeof(T))
桌子
.唯一键迭代器
.First(key=>key.Name==keyName)
.列迭代器);
}
公共bool包括(对象属性值、字符串属性名称、IType类型)
{
return_configuration.GetClassMapping(typeof(T))
.物业
.First(prop=>prop.Name==propertyName)
.列迭代器
.Where(col=>!col.IsFormula)
.Cast()
.Any(col=>\u keyColumns.Contains(col)))
}
}
我实际上还没有编译这个来检查它是否有效,所以YMMV。而且它肯定可以变得更有效!它也不会捕获任何错误条件(例如,如果您给它一个不正确的键名,或者一个未映射的类类型,那么它将崩溃)

干杯,
约翰

谢谢你!使用NHibernate.Cfg.Configuration是我需要的提示。我最初认为可以使用SessionFactory.GetClassMetadata()函数来解决这个问题。
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)))
    }
}