繁体   English   中英

如何使用nHibernate和QueryOver API获得明显的结果?

[英]How to get a distinct result with nHibernate and QueryOver API?

我有这个Repository方法

    public IList<Message> ListMessagesBy(string text, IList<Tag> tags, int pageIndex, out int count, out int pageSize)
    {
        pageSize = 10;
        var likeString = string.Format("%{0}%", text);
        var query = session.QueryOver<Message>()
            .Where(Restrictions.On<Message>(m => m.Text).IsLike(likeString) || 
            Restrictions.On<Message>(m => m.Fullname).IsLike(likeString));

        if (tags.Count > 0)
        {
            var tagIds = tags.Select(t => t.Id).ToList();
            query
                .JoinQueryOver<Tag>(m => m.Tags)
                .WhereRestrictionOn(t => t.Id).IsInG(tagIds);
        }            

        count = 0;
        if(pageIndex < 0)
        {
            count = query.ToRowCountQuery().FutureValue<int>().Value;
            pageIndex = 0;
        }
        return query.OrderBy(m => m.Created).Desc.Skip(pageIndex * pageSize).Take(pageSize).List();
    }

您提供自由文本搜索字符串和标签列表。 问题是,如果邮件有多个标签,则会列出重复的时间。 我想要一个基于Message实体的独特结果。 我看了看

Projections.Distinct

但它需要一个属性列表来处理不同的问题。 这条消息是我的实体根,大多数是在没有提供所有实体属性的情况下获得此行为的方法吗?

提前谢谢,安德斯

如果您使用的是ICriteria API,则需要:

.SetResultTransformer(new DistinctEntityRootTransformer())

如果您使用的是QueryOver API,则需要:

.TransformUsing(Transformers.DistinctRootEntity)

但请注意,这一切都发生在客户端,因此仍然会拉出所有重复的行。

尝试这样的事情

public IPagedList<Client> Find(int pageIndex, int pageSize)
{
    Client clientAlias = null;

    var query = Session.QueryOver<Client>(() => clientAlias)

        .Select(
            Projections.Distinct(
                Projections.ProjectionList()
                    .Add(Projections.Property<Client>(x => x.Id).As("Id"))
                    .Add(Projections.Property<Client>(x => x.Name).As("Name"))
                    .Add(Projections.Property<Client>(x => x.Surname).As("Surname"))
                    .Add(Projections.Property<Client>(x => x.GivenName).As("GivenName"))
                    .Add(Projections.Property<Client>(x => x.EmailAddress).As("EmailAddress"))
                    .Add(Projections.Property<Client>(x => x.MobilePhone).As("MobilePhone"))
            )
        )
        .TransformUsing(Transformers.AliasToBean<Client>())

        .OrderBy(() => clientAlias.Surname).Asc
        .ThenBy(() => clientAlias.GivenName).Asc;

    var count = query
        .ToRowCountQuery()
        .FutureValue<int>();

    return query
        .Take(pageSize)
        .Skip(Pagination.FirstResult(pageIndex, pageSize))
        .List<Client>()
        .ToPagedList(pageIndex, pageSize, count.Value);
}

您可以使用SelectList和GroupBy,例如:

tags.SelectList(t => t.SelectGroup(x => x.Id))

应该工作并生成相同的查询计划。

如果您需要组中的多个项目,请执行以下操作:

tags.SelectList(t => t.SelectGroup(x => x.Id)
                      .SelectGroup(x => x.Name)
               )

我最近创建了一个基于映射对象类型应用select distinct的方法。 它将此应用于IQueryOver对象(类的属性)。 方法还可以访问nhibernate配置。 您可以将这些添加为方法参数。 需要为生产工作,但方法在开发中工作得很好,到目前为止只用于一个实体。

创建此方法是因为我尝试在服务器级别分页我的数据,并且不同的结果转换器不起作用。

获得对象集合(query.List())后,可能必须重新加载对象以填充一个到多个子对象。 多个到一个映射将代表延迟加载。

 public void DistinctRootProjectionList<E>()
    {
        var classMapping = Context.Config.GetClassMapping(typeof(E));
        var propertyIterator = classMapping.UnjoinedPropertyIterator;
        List<IProjection> projections = new List<IProjection>();
        ProjectionList list = Projections.ProjectionList();

        list.Add(Projections.Property(classMapping.IdentifierProperty.Name), classMapping.IdentifierProperty.Name);

        foreach (var item in propertyIterator)
        {
            if (item.Value.IsSimpleValue || item.Value.Type.IsEntityType)
            {
                list.Add(Projections.Property(item.Name), item.Name);
            }
        }
        query.UnderlyingCriteria.SetProjection(Projections.Distinct(list));
        query.TransformUsing(Transformers.AliasToBean<E>());
    }

代码我用来加载一对多关系... T是实体类型。

for (int i = 0; i < resp.Data.Count; i++)
        {
            resp.Data[i] = session.Load<T>(GetInstanceIdValue(resp.Data[i]));
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM