Nhibernate query for items that have a Dictionary Property containing value

荒凉一梦 提交于 2019-11-28 01:05:20

问题


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

Assume:

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

and mapping:

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

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

with error

cannot dereference scalar collection element: Value

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


回答1:


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

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

The Item now has

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

Now we will extend the mapping:

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

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



来源:https://stackoverflow.com/questions/20829531/nhibernate-query-for-items-that-have-a-dictionary-property-containing-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!