簡體   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