如何选择与NHibernate字典值中的列? [英] How can I select a column within a dictionary value with nhibernate?

查看:223
本文介绍了如何选择与NHibernate字典值中的列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我也有类似这样的结构:

 公共类实体
{
公众诠释标识{得到;组; }
公众的IDictionary<字符串,EntityLocale>语言环境{搞定;组; }
}
公共类EntityLocale
{
公共字符串名称{;组; }
}
公共类EntityMap:ClassMap<实体GT;
{
公共EntityMap()
{
的hasMany(X => x.Locales)
.AsMap<串>(区域设置)
.Component(
C => {
c.Map(X => x.Name);
}
);
}
}

和我想收到的产品语言环境的所有名称与一个恩键。使用LINQ这将是:



  VAR名= Session.QueryOver<产品>()名单()选择(X = > x.Locales [连接]名称).ToList()。 



我如何与NHibernate实现这一目标? (我不在乎它是否QueryOver或标准的API,我只是不希望选择的一切)。



更新



我想出了下面的丑陋的黑客攻击(这是我很不满意,我不希望在我的代码的任何SQL):

  VAR名= Session.CreateSQLQuery(选择的名字从ProductLocales其中locale ='恩')列表<串>()


解决方案

对于这些情况,NHibernate的具有非常不错的解决方案:的 18.1。 NHibernate的过滤器。最后,我们将选择产品和应用的过滤器的词典中......因此只能有的SingleOrDefault()区域设置



过滤器Definiton

$ b $项目b

 公共类CulturFilter:FilterDefinition 
{
公共CulturFilter()
{
WithName(CulturFilter)
.AddParameter(文化,NHibernate.NHibernateUtil.String);
}
}

和应用它

 的hasMany(X => x.Locales)
.AsMap<串>(区域设置)

.ApplyFilter< CulturFilter>(区域设置=:文化))
;



从那个时候起,只要你能在会话(即使有一些AOP过滤器)过滤器,你可以肯定的是,的IDictionary 包含一个(或无)元素..

  session.EnableFilter(CultureFilter)
.SetParameter(文化,恩);

//应用于每次
VAR标准= session.CreateCritieria ...
VAR的查询= session.QueryOver ....

有与一些更多的联系相近岗位,如果需要 HTTP ://stackoverflow.com/a/17109300/1679310



编辑:直接限制列区域设置,让名

列表

其他方法(保持当前的解决方案几乎相同的),其可用于(我知道)是延长LocalEntity映射

 公共类EntityLocale 
{
公共虚拟字符串CultureName {搞定;组; }
公共虚拟字符串名称{;组; }
}
公共类EntityMap:ClassMap<实体GT;
{
公共EntityMap()
{
的hasMany(X => x.Locales)
.AsMap<串>(区域设置)
.Component(
C => {
c.Map(X =方式> x.CultureName).Formula(区域设置)Not.Insert()Not.Update();
c.Map(X => x.Name);
}
);
}
}



到这一点,我们可以得到所有的名单 EN这样的名称:

  VAR标准= 
session.QueryOver<实体>()
。 JoinQueryOver<&IDictionary的LT;字符串,EntityLocale>>(C => c.Locales)
.UnderlyingCriteria;

无功名单=标准
。新增(Restrictions.Eq(CultureName,恩))
.SetProjection(Projections.SqlProjection(名
,新的String [] {名称}
,新ITYPE [] {NHibernateUtil.String}))
的.List()
.Cast<串>()
。 &了ToList LT;弦乐>();

现在我们有一个包含所有姓名列表从EntityLocale的恩文化


过滤

I have structure similar to this:

public class Entity
{
    public int Id { get; set; }
    public IDictionary<string, EntityLocale> Locales { get; set; }
}
public class EntityLocale
{
    public string Name { get; set; }
}
public class EntityMap : ClassMap<Entity>
{
    public EntityMap()
    {
        HasMany(x => x.Locales)
                .AsMap<string>("Locale")
                .Component(
                c => {
                         c.Map(x => x.Name);
                     }
                );
    }
}

And I want to recieve all names of product locales with a "en" key. With linq it will be:

var names = Session.QueryOver<Product>().List().Select(x => x.Locales["en"].Name).ToList();

How do I achieve this with nhibernate? (I don't care if it's QueryOver or Criteria api, I just don't want to select everything).

Update

I came up with the following ugly hack (which I'm not satisfied with, I don't want any sql in my code):

var names = Session.CreateSQLQuery("SELECT Name FROM ProductLocales WHERE Locale = 'en'").List<string>()

解决方案

For these cases, NHibernate has very nice solution: 18.1. NHibernate filters. At the end, we will select Product and apply filter on the dictionary... therefore having only SingleOrDefault() item in the Locales.

Definiton of the Filter

public class CulturFilter : FilterDefinition
{
  public CulturFilter()
  {
    WithName("CulturFilter")
        .AddParameter("culture",NHibernate.NHibernateUtil.String);
  }
}

and apply it

HasMany(x => x.Locales)
  .AsMap<string>("Locale")
  ... 
  .ApplyFilter<CulturFilter>("Locale = :culture"))
;

From that moment, whenever you enable the filter in the session (even with some AOP filter), you can be sure that the IDictionary contains exactly one (or none) element..

session.EnableFilter("CultureFilter")
    .SetParameter("culture", "en");

// applied every time
var criteria = session.CreateCritieria...
var query = session.QueryOver....

There is similar posts with some more links if needed http://stackoverflow.com/a/17109300/1679310

EDIT: Restricting the column "Locale" directly, getting the list of Names

Other approach (keeping the current solution almost the same) which could be used (and I know about) is to extend the LocalEntity mapping

public class EntityLocale
{
    public virtual string CultureName { get; set; }
    public virtual string Name { get; set; }
}
public class EntityMap : ClassMap<Entity>
{
    public EntityMap()
    {
        HasMany(x => x.Locales)
            .AsMap<string>("Locale")
            .Component(
            c => {
                c.Map(x => x.CultureName).Formula("Locale").Not.Insert().Not.Update();
                c.Map(x => x.Name);
            }
        );
    }
}

Having this, we can get the list of all "en" Names like this:

var criteria = 
    session.QueryOver<Entity>()
    .JoinQueryOver<IDictionary<string, EntityLocale>>(c => c.Locales)
    .UnderlyingCriteria;

var list = criteria
    .Add(Restrictions.Eq("CultureName", "en"))
    .SetProjection(Projections.SqlProjection("Name"
        , new string[] { "name" }
        , new IType[] { NHibernateUtil.String }))
    .List()
    .Cast<string>()
    .ToList<String>();

Now we have a list containing all the Names from EntityLocale filtered by "en" culture

这篇关于如何选择与NHibernate字典值中的列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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