NHibernate QueryOver - 结果太多的集合

时间:2013-09-13 11:15:26

标签: c# mysql nhibernate queryover

亲爱的NHibernate用户,

我一直在尝试,阅读和其他2天,但仍然无法解决这个问题,尽管我认为使用QueryOver API这是一项简单的任务。

这是我的两个实体:

ATTRIBUTE
---------------------------
public int Id { get; set; }
public int LanguageId { get; set; }
public string Title { get; set; }
public IList<Option> Options { get; set; }


OPTION
---------------------------
public int Id { get; set; }
public Attribute Attribute { get; set; }
public int LanguageId { get; set; }
public string Title { get; set; }

映射如下:

<class name="Attribute" lazy="false" table="attribute" dynamic-insert="true" dynamic-update="true" select-before-update="true">
    <id name="Id" column="attribute_id" type="System.Int32">
        <generator class="native"/>
    </id>

    <bag name="Options" lazy="false" cascade="all">
        <key column="attribute_id" not-null="true" />
        <one-to-many class="Option" not-found="ignore" />
    </bag>

    <join table="attribute_i18n" inverse="true" fetch="join">
        <key column="attribute_id" not-null="true"/>
        <property name="LanguageId" column="language_id" type="System.Int32" not-null="true" />
        <property name="Title" column="title" type="System.String" length="255" not-null="true" />
    </join>
</class>

<class name="Option" lazy="false" table="options" dynamic-insert="true" dynamic-update="true" select-before-update="true">
    <id name="Id" column="option_id" type="System.Int32">
        <generator class="native"/>
    </id>

    <many-to-one name="Attribute" class="Attribute" column="attribute_id" not-null="true" />

    <join table="option_i18n" inverse="true" fetch="join">
        <key column="option_id" not-null="true"/>
        <property name="LanguageId" column="language_id" type="System.Int32" not-null="true" />
        <property name="Title" column="title" type="System.String" length="255" not-null="true" />
    </join>
</class>

请注意,两个表都加入了自己的“i18n”-table(支持多语言条目),并参考其language_id列。

此外,我尝试使用QueryOver API,并在LanguageId设置为1的情况下查询Options-property。

经过大量的拔毛后,我的询问又回到了我的开始:

Attribute attribute = null;
Option option = null;

result = Session.QueryOver(() => attribute)
                .Where(() => attribute.LanguageId == 1)
                .Left.JoinAlias(i => i.Options, () => option)
                .Where(() => option.LanguageId == 1)
                .TransformUsing(Transformers.DistinctRootEntity)
                .List();

那么,对我的问题: 此查询继续在我的选项列表中为我提供一组双选项(对于language_id 1和2)。我想只选择language_id = 1,但令我沮丧的是,API不理解我(或者反过来了吗?)。

非常感谢任何有关如何使我的查询对我的OPTION包收集的帮助! :-)谢谢!

米卡尔

1 个答案:

答案 0 :(得分:0)

我害怕,他的意志不行。根据设计和<join>的性质。如文档中所述:

  

5.1.19. join

     

使用<join>元素,可以将一个类的属性映射到多个表   表之间存在 1对1 关系。

如何(我愿意)解决这个问题的方式有点不同。我有一个对象Language,该选项包含语言集合

public virtual IList<Language> Languages {get; set;}

映射例如是<bag>

<bag name="Languages"  batch-size="25"
  cascade="all-delete-orphan" inverse="true" >
  <key column="option_id" />
  <one-to-many class="Language" />

  <filter name="LanguagFilter" condition=":languageId = LanguageId" />
</bag>

诀窍在于过滤器。这是 where mapping-attribute(18.1.NHibernate过滤器)的动态版本

<filter-def name="LanguageFilter" >
  <filter-param name="languageId" type="Int32" />
</filter-def>

然后,我们可以打开过滤器,用于当前会话的所有操作。每个请求(如果是Web应用程序)只有一次,在一些AOP中,我们知道语言ID:

var filter = session.EnableFilter("LanguageFilter");
filter.SetParameter("languageId", theCurrentLanguageIdFromUser);

最后,我们知道,集合语言只包含一条记录,我们始终可以访问.First()。没有更多语言的多重结果

另请参阅:https://stackoverflow.com/a/16625867/1679310https://stackoverflow.com/a/18479266/1679310