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

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

问题描述



假设:

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

和映射:





$ HasMany(x =&x; xDictionaryProperty)
.Access.ReadOnlyPropertyThroughCamelCaseField(Prefix.Underscore)
.AsMap< string>(
index => index.Column(IDNumber)。长度(666)

.Cascade.AllDeleteOrphan()
.Fetch.Join();类型< string>

$ / code>

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

  session.Query< Item>()。其中​​(r => r.DictionaryProperty。任何(g => g.Value ==SomeText))

带有错误

 无法解引用标量集合元素:Value 

那么有什么办法可以在NHibernate中实现呢? Linq不是独家要求,但它的优先。不是说我没有兴趣查询可以使用 .ContainsKey 来实现的字典。 ο这个是相似的,但不相同。

$ b处理 IDictionary< TValueType,TValueType> 通常会带来更多的问题,而不是优点。一种解决方法是使用和来引入一个新的对象(我将称之为MyWrapper) code> Value (只是一个例子命名)

这样我们必须1)创建新的对象(MyWrapper),2)调整映射,就是这样。没有其他的变化...所以原来的东西(映射,属性)将工作,因为我们将使用不同的(只读)属性来查询

  public class MyWrapper 
{
public virtual int Key {get;组; }
公共虚拟字符串值{get;组; }



$ b $ p


$ b

  public class Item 
{
//保留Insert / Updae的存在
public virtual IDictionary< int,string> DictionaryProperty {get; set;}

//映射
私有IList< MyWrapper> _properties = new List< MyWrapper>();

//将其发布为只读
公共虚拟IEnumerable< MyWrapper>属性
{
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)。列(TextField)
})
...
;

以及Query将按预期工作:

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

经验,这个解决方法不应该是解决方法。这是首选的方式。 NHibernate支持很多功能,但是使用Objects可以带来更多的利润


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

解决方案

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

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

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