Nhibernate 查询具有包含值的字典属性的项目 [英] Nhibernate query for items that have a Dictionary Property containing value

查看:18
本文介绍了Nhibernate 查询具有包含值的字典属性的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一种在 Nhibernate 中查询具有包含值的字典属性的项目的方法.

I need a way to query in Nhibernate for items that have a Dictionary Property containing value.

假设:

public class Item
{
     public virtual IDictionary<int, string> DictionaryProperty {get; set;}
}

和映射:

    public ItemMap()
    {
        HasMany(x => x.DictionaryProperty)
            .Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore)
            .AsMap<string>(
                index => index.Column("IDNumber").Type<int>(),
                element => element.Column("TextField").Type<string>().Length(666)
                )
            .Cascade.AllDeleteOrphan()
            .Fetch.Join();
    }

我想查询所有字典值为SomeText"的Item.Linq 中的以下示例失败:

I want to query all Items that have a dictionary value of "SomeText". The following example in Linq fails:

session.Query<Item>().Where(r => r.DictionaryProperty.Any(g => g.Value == "SomeText"))

有错误

cannot dereference scalar collection element: Value

那么有什么办法可以在 NHibernate 中实现呢?Linq 不是唯一的要求,而是它的首选.并不是说我对查询可以使用 .ContainsKey 实现的字典 keys 不感兴趣.Φορ 这个类似但不一样

So is there any way to achieve that in NHibernate? Linq is not an exclusive requirement but its preffered. Not that I'm not interested to query over dictionary keys that can be achieved using .ContainsKey . Φορ this is similar but not the same

推荐答案

处理 IDictionary 通常带来的问题多于优势.一种解决方法是引入一个新对象(我将称其为MyWrapper),其属性为KeyValue (只是一个命名示例).

Handling IDictionary<TValueType, TValueType> would usually bring more issues than advantages. One way, workaround, is to introduce a new object (I will call it MyWrapper) with properties Key and Value (just an example naming).

这样我们必须 1) 创建新对象 (MyWrapper),2) 调整映射,仅此而已.没有其他变化......所以原始的东西(映射,属性)将起作用,因为我们将使用不同的(只读)属性进行查询

This way we have to 1) create new object (MyWrapper), 2) adjust the mapping and that's it. No other changes... so the original stuff (mapping, properties) will work, because we would use different (readonly) property for querying

public class MyWrapper
{
    public virtual int Key { get; set; }
    public virtual string Value { get; set; }
}

物品现在有

public class Item
{
    // keep the existing for Insert/Updae
    public virtual IDictionary<int, string> DictionaryProperty {get; set;}

    // map it
    private IList<MyWrapper> _properties = new List<MyWrapper>();

    // publish it as readonly
    public virtual IEnumerable<MyWrapper> Properties
    {
        get { return new ReadOnlyCollection<MyWrapper>(_properties); }
    }
}

现在我们将扩展映射:

HasMany(x => x.Properties)
    .Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore)
    .Component(c =>
    {
        c.Map(x => x.Key).Column("IDNumber")
        c.Map(x => x.Value).Column("TextField")
    })
    ...
    ;

还有查询,它将按预期工作:

And the Query, which will work as expected:

session
    .Query<Item>()
    .Where(r => 
        r.Properties.Any(g => g.Value == "SomeText")
    )

注意:根据我的经验,这种变通方法不应该是变通方法.这是首选方式.NHibernate 支持很多特性,但使用 Objects 带来更多收益

NOTE: From my experience, this workaround should not be workaround. It is preferred way. NHibernate supports lot of features, but working with Objects brings more profit

这篇关于Nhibernate 查询具有包含值的字典属性的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆