NHibernate QueryOver - 结果太多的集合 [英] NHibernate QueryOver - collection with too many results
问题描述
尊敬的 NHibernate 用户:
Dear NHibernate users,
我已经尝试、阅读和诸如此类的东西已经 2 天了,但仍然无法解决这个问题,尽管我认为使用 QueryOver API 是一件容易的事.
I've been trying, reading and whatnot for 2 days now, but still can't figure this out, even though I presumed it to be an easy task with 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"表(支持多语言条目),并引用其 language_id 列.
Note that both tables join towards its own "i18n"-table (support of multilingual entries), and refer to its language_id column.
此外,我尝试使用 QueryOver API,并在 LanguageId 设置为 1 的情况下查询 Options-property 的那些选项.
Furthermore, I try to use the QueryOver API, and query the Options-property for those options with LanguageId set to 1.
拉了很多头发后,我的查询又回到了我开始的地方:
After a lot of hair pulling, my query is back to what I started with:
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 不理解我(..或者相反?).
So, to my problem: This query keeps on giving me a double set of options in my option list (for language_id 1 and 2). I want to select only language_id = 1, but to my frustration the API doesn't understand me (..or was it the other way around?).
非常感谢有关如何使我的查询与我的 OPTION 包集合相匹配的任何帮助!:-) 谢谢!
Any help on how to make my query work against my bag-collection of OPTIONs is greatly appreciated! :-) Thanks!
米卡尔
推荐答案
我担心,他不会工作.根据
的设计和性质.如文档中所述:
I am afraid, that his won't work. By design and the nature of the <join>
. As stated in the documentation:
使用
元素,可以将一个类的属性映射到多个表,当表之间存在 1 对 1 关系.
Using the <join>
element, it is possible to map properties of one class to several tables, when
there's a 1-to-1 relationship between the tables.
如何(我愿意)解决这个问题的方式有点不同.我有一个对象 Language
,Option 有语言的集合
The way how to (I do) solve this issue is a bit different. I have an object Language
, the Option has colleciton of languages
public virtual IList<Language> Languages {get; set;}
映射例如
<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 映射属性(18.1. NHibernate 过滤器)
The trick is in the filter. This is a dynamic version of the where mapping-attribute (18.1. NHibernate filters)
<filter-def name="LanguageFilter" >
<filter-param name="languageId" type="Int32" />
</filter-def>
然后,我们可以为当前会话的所有操作打开过滤器.每个请求(如果是 Web 应用程序)只有一次,在某个 AOP 中,我们知道语言 ID:
Then, we can turn the filter on, for all operations of the current session. Only once per request (if web app), inside some AOP, where we know the language id:
var filter = session.EnableFilter("LanguageFilter");
filter.SetParameter("languageId", theCurrentLanguageIdFromUser);
最后,我们知道,Languages 集合只包含一条记录,我们总是可以访问 .First()
.更多语言不再有多重结果
And finally, we know, that the collection Languages contains only one record and we can always access .First()
. No more multiple results with more languages
另见:https://stackoverflow.com/a/16625867/1679310、https://stackoverflow.com/a/18479266/1679310
这篇关于NHibernate QueryOver - 结果太多的集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!