[英]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.