Adding order and slice support for content manager query

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4042275
This commit is contained in:
loudej
2009-11-26 01:17:48 +00:00
parent cc57dae5ca
commit 51f99de109
5 changed files with 130 additions and 17 deletions

View File

@@ -116,8 +116,8 @@ namespace Orchard.Tests.Models {
[Test]
public void AllItemsAreReturnedByDefault() {
AddSampleData();
var allItems = _manager.Query().Select();
var allItems = _manager.Query().List();
Assert.That(allItems.Count(), Is.EqualTo(4));
Assert.That(allItems.Count(x => x.Has<Alpha>()), Is.EqualTo(1));
@@ -125,12 +125,12 @@ namespace Orchard.Tests.Models {
Assert.That(allItems.Count(x => x.Has<Gamma>()), Is.EqualTo(1));
Assert.That(allItems.Count(x => x.Has<Delta>()), Is.EqualTo(1));
}
[Test]
public void SpecificTypeIsReturnedWhenSpecified() {
AddSampleData();
var alphaBeta = _manager.Query().ForType("alpha", "beta").Select();
var alphaBeta = _manager.Query().ForType("alpha", "beta").List();
Assert.That(alphaBeta.Count(), Is.EqualTo(2));
Assert.That(alphaBeta.Count(x => x.Has<Alpha>()), Is.EqualTo(1));
@@ -138,7 +138,7 @@ namespace Orchard.Tests.Models {
Assert.That(alphaBeta.Count(x => x.Has<Gamma>()), Is.EqualTo(0));
Assert.That(alphaBeta.Count(x => x.Has<Delta>()), Is.EqualTo(0));
var gammaDelta = _manager.Query().ForType("gamma", "delta").Select();
var gammaDelta = _manager.Query().ForType("gamma", "delta").List();
Assert.That(gammaDelta.Count(), Is.EqualTo(2));
Assert.That(gammaDelta.Count(x => x.Has<Alpha>()), Is.EqualTo(0));
@@ -155,7 +155,7 @@ namespace Orchard.Tests.Models {
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "three"; });
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "four"; });
_session.Flush();
var twoOrFour = _manager.Query().Where<GammaRecord>(x => x.Frap == "one" || x.Frap == "four").Select();
var twoOrFour = _manager.Query().Where<GammaRecord>(x => x.Frap == "one" || x.Frap == "four").List();
Assert.That(twoOrFour.Count(), Is.EqualTo(2));
Assert.That(twoOrFour.Count(x => x.Has<Gamma>()), Is.EqualTo(2));
@@ -167,8 +167,8 @@ namespace Orchard.Tests.Models {
[Test]
public void EmptyWherePredicateRequiresRecord() {
AddSampleData();
var gammas = _manager.Query().Where<GammaRecord>().Select();
var deltas = _manager.Query().Where<DeltaRecord>().Select();
var gammas = _manager.Query().Where<GammaRecord>().List();
var deltas = _manager.Query().Where<DeltaRecord>().List();
Assert.That(gammas.Count(), Is.EqualTo(1));
Assert.That(deltas.Count(), Is.EqualTo(1));
@@ -176,6 +176,56 @@ namespace Orchard.Tests.Models {
Assert.That(deltas.AsPart<Delta>().Single().Record.Quux, Is.EqualTo("the quux value"));
}
[Test]
public void OrderMaySortOnJoinedRecord() {
AddSampleData();
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "one"; });
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "two"; });
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "three"; });
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "four"; });
_session.Flush();
var ascending = _manager.Query("gamma")
.OrderBy<GammaRecord, string>(x => x.Frap)
.List<Gamma>();
Assert.That(ascending.Count(), Is.EqualTo(5));
Assert.That(ascending.First().Record.Frap, Is.EqualTo("four"));
Assert.That(ascending.Last().Record.Frap, Is.EqualTo("two"));
var descending = _manager.Query("gamma")
.OrderByDescending<GammaRecord, string>(x => x.Frap)
.List<Gamma>();
Assert.That(descending.Count(), Is.EqualTo(5));
Assert.That(descending.First().Record.Frap, Is.EqualTo("two"));
Assert.That(descending.Last().Record.Frap, Is.EqualTo("four"));
}
[Test]
public void SkipAndTakeProvidePagination() {
AddSampleData();
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "one"; });
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "two"; });
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "three"; });
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "four"; });
_session.Flush();
var reverseById = _manager.Query()
.OrderByDescending<ContentItemRecord, int>(x => x.Id)
.List();
var subset = _manager.Query()
.OrderByDescending<ContentItemRecord, int>(x => x.Id)
.Slice(2, 3);
Assert.That(subset.Count(), Is.EqualTo(3));
Assert.That(subset.First().Id, Is.EqualTo(reverseById.Skip(2).First().Id));
Assert.That(subset.Skip(1).First().Id, Is.EqualTo(reverseById.Skip(3).First().Id));
Assert.That(subset.Skip(2).First().Id, Is.EqualTo(reverseById.Skip(4).First().Id));
}
}
}

View File

@@ -36,11 +36,12 @@ namespace Orchard.Users.Controllers {
public ActionResult Index() {
var model = new UsersIndexViewModel();
model.Rows = _userRepository.Fetch(x => x.UserName != null)
.Select(x => new UsersIndexViewModel.Row {
User = _contentManager.Get(x.Id).As<User>()
})
.ToList();
var users = _contentManager.Query("user")
.Where<UserRecord>(x => x.UserName != null)
.List<User>();
model.Rows = users.Select(x => new UsersIndexViewModel.Row {User = x}).ToList();
return View(model);
}

View File

@@ -33,6 +33,18 @@ namespace Orchard.Models {
}
public static IContentQuery Query(this IContentManager manager, params string[] contentTypeNames) {
return manager.Query().ForType(contentTypeNames);
}
public static IEnumerable<T> List<T>(this IContentManager manager, params string[] contentTypeNames) where T : class, IContent {
return manager.Query(contentTypeNames).List<T>();
}
public static IEnumerable<T> List<T>(this IContentQuery query) where T : class, IContent {
return query.List().AsPart<T>();
}
public static bool Is<T>(this IContent content) {
return content == null ? false : content.ContentItem.Has(typeof(T));

View File

@@ -37,6 +37,11 @@ namespace Orchard.Models {
ICriteria BindCriteriaByPath(string path) {
var itemCriteria = BindItemCriteria();
// special if the content item is ever used as where or order
if (path == typeof(ContentItemRecord).Name)
return itemCriteria;
return itemCriteria.GetCriteriaByPath(path) ?? itemCriteria.CreateCriteria(path);
}
@@ -65,18 +70,60 @@ namespace Orchard.Models {
// attach the criterion from the predicate to this query's criteria for the record
var recordCriteria = BindCriteriaByPath(typeof(TRecord).Name);
foreach (var entry in criteria.IterateExpressionEntries()) {
recordCriteria.Add(entry.Criterion);
foreach (var expressionEntry in criteria.IterateExpressionEntries()) {
recordCriteria.Add(expressionEntry.Criterion);
}
return this;
}
public IContentQuery OrderBy<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) {
// build a linq to nhibernate expression
var options = new QueryOptions();
var queryProvider = new NHibernateQueryProvider(BindSession(), options);
var queryable = new Query<TRecord>(queryProvider, options).OrderBy(keySelector);
public IEnumerable<ContentItem> Select() {
// translate it into the nhibernate ordering
var criteria = (CriteriaImpl)queryProvider.TranslateExpression(queryable.Expression);
// attaching orderings to the query's criteria
var recordCriteria = BindCriteriaByPath(typeof(TRecord).Name);
foreach(var ordering in criteria.IterateOrderings()){
recordCriteria.AddOrder(ordering.Order);
}
return this;
}
public IContentQuery OrderByDescending<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) {
// build a linq to nhibernate expression
var options = new QueryOptions();
var queryProvider = new NHibernateQueryProvider(BindSession(), options);
var queryable = new Query<TRecord>(queryProvider, options).OrderByDescending(keySelector);
// translate it into the nhibernate ICriteria implementation
var criteria = (CriteriaImpl)queryProvider.TranslateExpression(queryable.Expression);
// attaching orderings to the query's criteria
var recordCriteria = BindCriteriaByPath(typeof(TRecord).Name);
foreach (var ordering in criteria.IterateOrderings()) {
recordCriteria.AddOrder(ordering.Order);
}
return this;
}
public IEnumerable<ContentItem> List() {
return BindItemCriteria()
.List<ContentItemRecord>()
.Select(x => ContentManager.Get(x.Id));
}
public IEnumerable<ContentItem> Slice(int skip, int count) {
return BindItemCriteria()
.SetFirstResult(skip)
.SetMaxResults(count)
.List<ContentItemRecord>()
.Select(x => ContentManager.Get(x.Id));
}
}
}

View File

@@ -11,7 +11,10 @@ namespace Orchard.Models {
IContentQuery Where<TRecord>();
IContentQuery Where<TRecord>(Expression<Func<TRecord, bool>> predicate);
IEnumerable<ContentItem> Select();
IContentQuery OrderBy<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector);
IContentQuery OrderByDescending<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector);
IEnumerable<ContentItem> List();
IEnumerable<ContentItem> Slice(int skip, int count);
}
}