NHibernate的许多人在许多疑问许多成果 [英] NHibernate many to many results in many queries

查看:252
本文介绍了NHibernate的许多人在许多疑问许多成果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发ASP.NET MVC中一个书签系统,我用NHibernate的查询数据库。

I am developing a bookmark system in ASP.NET MVC and I use NHibernate to query the database.

我有一个多对多的关系:

I have a many to many relationship:


  • 的书签可以有很多标签

  • 一个标签可以有很多书签

模型:

public class Bookmark
{
    public virtual string Title { get; set; }
    public virtual string Link { get; set; }
    public virtual User User { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}

public class Tag
{
    public virtual string Title { get; set; }
    public virtual string Description { get; set; }
    public virtual User User { get; set; }
    public virtual ICollection<Bookmark> Bookmarks { get; set; }
}



我希望得到一个标签,环槽的书签,并为每个书签环槽的标签。要做到这一点我用这样的:

I want to get a tag, loop trough its bookmarks, and for each bookmark loop trough its tags. To do this I used this:

public Tag GetTagByTitle(string username, string title)
{
    ICriteria criteriaQuery = SessionFactory.GetCurrentSession()
        .CreateCriteria(typeof(Tag))
        .SetFetchMode("Bookmarks", FetchMode.Eager)
        .CreateAlias("User", "User")
        .Add(Restrictions.Eq("Title", title))
        .Add(Restrictions.Eq("User.Username", username));

    IList<Tag> tags = criteriaQuery.List<Tag>();
    Tag tag = tags.FirstOrDefault();

    return tag;
}

这给了我与它的书签标记。然而,对于每个书签会自动做另一个查询来获取它的标签(延迟加载?)。所以,如果我有10个书签,我得到1 + 10的查询。 ?与NHibernate分析器(3书签)是否有可能有一个或两个查询做到这一点。

This gives me a tag with its bookmarks. However for each bookmark it is doing another query automatically to obtain its tags (lazy loading?). So if I have 10 bookmarks I get 1 + 10 queries. Is it possible to do this with one or two queries?

例如:

推荐答案

您可以使用 CreateAlias 来预先抓取书签,它也可以让你去挖掘另一层更深指定要如何取标签。

You can use CreateAlias to eagerly fetch the bookmarks, and it will also allow you to dig another layer deeper to specify how you want to fetch the tags.

ICriteria criteriaQuery = SessionFactory.GetCurrentSession()
    .CreateCriteria(typeof(Tag))
    .CreateAlias("Bookmarks", "b", JoinType.LeftOuterJoin)
    .CreateAlias("b.Tags", "bt", JoinType.LeftOuterJoin)
    .CreateAlias("User", "User")
    .Add(Restrictions.Eq("Title", title))
    .Add(Restrictions.Eq("User.Username", username))
    .SetResultTransformer(Transformers.DistinctRootEntity);



编辑:固定查询我们对此深感抱歉。显然 SetFetchMode 仅适用于关系直接关闭该查询的根实体中。与 CreateAlias 替换它修复该问题。

Fixed query. Sorry about that. Apparently SetFetchMode only works for relationships directly off of the root entity of the query. Replacing it with CreateAlias fixes the issue.

通过所有这些左外连接来收藏,你'会需要修改你的实体位和更新您的映射,以防止重复entiries从显示集合起来。相反的ICollection<的; T> ,使用的ISet< T> Iesi.Collections。通用命名空间,并改变你的映射使用<设置/> 而不是<袋/>

With all of these left-outer-joins to collections, you'll need to modify your entities a bit and update your mappings to prevent duplicate entiries from showing up in the collections. Instead of ICollection<T>, use ISet<T> from the Iesi.Collections.Generic namespace, and change your mappings to use <set/> instead of <bag/>.

这篇关于NHibernate的许多人在许多疑问许多成果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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