#19703, 19209: Fixing Hql queries with duplicated roots

Work Items: 19703, 19209

--HG--
branch : 1.x
This commit is contained in:
Sebastien Ros
2013-05-23 11:15:15 -07:00
parent 79178ed480
commit a094efac2d
4 changed files with 70 additions and 17 deletions

View File

@@ -953,6 +953,31 @@ namespace Orchard.Tests.ContentManagement {
Assert.That(firstResults.Distinct().Count(), Is.GreaterThan(1));
}
[Test]
public void ShouldSortByProperty() {
var dt = new DateTime(1980, 1, 1);
_manager.Create<LambdaPart>("lambda", init => {
init.Record.IntegerStuff = 1;
});
_manager.Create<LambdaPart>("lambda", init => {
init.Record.IntegerStuff = 2;
});
_manager.Create<LambdaPart>("lambda", init => {
init.Record.IntegerStuff = 3;
});
_session.Flush();
var results =_manager.HqlQuery().Join(alias => alias.ContentPartRecord<LambdaRecord>()).OrderBy(x => x.ContentPartRecord<LambdaRecord>(), order => order.Asc("IntegerStuff")).List();
Assert.That(results.Count(), Is.EqualTo(3));
Assert.That(results.Skip(0).First().As<LambdaPart>().Record.IntegerStuff, Is.EqualTo(1));
Assert.That(results.Skip(1).First().As<LambdaPart>().Record.IntegerStuff, Is.EqualTo(2));
Assert.That(results.Skip(2).First().As<LambdaPart>().Record.IntegerStuff, Is.EqualTo(3));
}
[Test]
public void ShouldQueryUsingOperatorNot() {
var dt = new DateTime(1980, 1, 1);

View File

@@ -289,9 +289,10 @@ namespace Orchard.ContentManagement {
return itemsById.TryGetValue(id, out values) ? values : Enumerable.Empty<ContentItem>();
}).AsPart<T>().ToArray();
}
public IEnumerable<T> GetManyByVersionId<T>(IEnumerable<int> versionRecordIds, QueryHints hints) where T : class, IContent {
var contentItemVersionRecords = GetManyImplementation(hints, (contentItemCriteria, contentItemVersionCriteria) =>
public IEnumerable<ContentItem> GetManyByVersionId(IEnumerable<int> versionRecordIds, QueryHints hints) {
var contentItemVersionRecords = GetManyImplementation(hints, (contentItemCriteria, contentItemVersionCriteria) =>
contentItemVersionCriteria.Add(Restrictions.In("Id", versionRecordIds.ToArray())));
var itemsById = contentItemVersionRecords
@@ -302,7 +303,11 @@ namespace Orchard.ContentManagement {
return versionRecordIds.SelectMany(id => {
IGrouping<int, ContentItem> values;
return itemsById.TryGetValue(id, out values) ? values : Enumerable.Empty<ContentItem>();
}).AsPart<T>().ToArray();
}).ToArray();
}
public IEnumerable<T> GetManyByVersionId<T>(IEnumerable<int> versionRecordIds, QueryHints hints) where T : class, IContent {
return GetManyByVersionId(versionRecordIds, hints).AsPart<T>();
}
private IEnumerable<ContentItemVersionRecord> GetManyImplementation(QueryHints hints, Action<ICriteria, ICriteria> predicate) {

View File

@@ -159,10 +159,11 @@ namespace Orchard.ContentManagement {
public IEnumerable<ContentItem> Slice(int skip, int count) {
ApplyHqlVersionOptionsRestrictions(_versionOptions);
var hql = ToHql(false);
var query = _session
.CreateQuery(hql)
.SetCacheable(true)
.SetResultTransformer(new DistinctRootEntityResultTransformer());
;
if (skip != 0) {
query.SetFirstResult(skip);
@@ -171,29 +172,49 @@ namespace Orchard.ContentManagement {
query.SetMaxResults(count);
}
return query.List<ContentItemVersionRecord>()
.Select(x => ContentManager.Get(x.Id, VersionOptions.VersionRecord(x.Id)))
.ToReadOnlyCollection();
var ids = query
.SetResultTransformer(Transformers.AliasToEntityMap)
.List<IDictionary>()
.Select(x => (int)x["Id"]);
return ContentManager.GetManyByVersionId(ids, QueryHints.Empty);
}
public int Count() {
ApplyHqlVersionOptionsRestrictions(_versionOptions);
return Convert.ToInt32(
_session.CreateQuery(ToHql(true))
.SetCacheable(true)
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.UniqueResult()
);
var hql = ToHql(true);
hql = "select count(Id) from Orchard.ContentManagement.Records.ContentItemVersionRecord where Id in ( " + hql + " )";
return Convert.ToInt32(_session.CreateQuery(hql)
.SetCacheable(true)
.UniqueResult())
;
}
public string ToHql(bool count) {
var sb = new StringBuilder();
if (count) {
sb.Append("select count(civ) ").AppendLine();
sb.Append("select distinct civ.Id as Id").AppendLine();
}
else {
sb.Append("select civ ").AppendLine();
sb.Append("select distinct civ.Id as Id");
// add sort properties in the select
foreach (var sort in _sortings) {
var sortFactory = new DefaultHqlSortFactory();
sort.Item2(sortFactory);
if (!sortFactory.Randomize) {
sb.Append(", ");
sb.Append(sort.Item1.Name).Append(".").Append(sortFactory.PropertyName);
}
else {
// select distinct can't be used with newid()
sb.Replace("select distinct", "select ");
}
}
sb.AppendLine();
}
sb.Append("from ").Append(_from.TableName).Append(" as ").Append(_from.Name).AppendLine();
@@ -232,7 +253,8 @@ namespace Orchard.ContentManagement {
sort.Item2(sortFactory);
if (sortFactory.Randomize) {
sb.Append(" newid()");
//sb.Append(" newid()");
sb.Append("newid()");
}
else {
sb.Append(sort.Item1.Name).Append(".").Append(sortFactory.PropertyName);

View File

@@ -63,6 +63,7 @@ namespace Orchard.ContentManagement {
IEnumerable<T> GetMany<T>(IEnumerable<int> ids, VersionOptions options, QueryHints hints) where T : class, IContent;
IEnumerable<T> GetManyByVersionId<T>(IEnumerable<int> versionRecordIds, QueryHints hints) where T : class, IContent;
IEnumerable<ContentItem> GetManyByVersionId(IEnumerable<int> versionRecordIds, QueryHints hints);
void Publish(IContent content);
void Unpublish(IContent content);