Created
June 29, 2011 19:16
-
-
Save ldhertert/1054658 to your computer and use it in GitHub Desktop.
Linq implementation of ContentQuery
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using NHibernate; | |
using NHibernate.Criterion; | |
using NHibernate.Impl; | |
using NHibernate.Linq; | |
using Orchard.ContentManagement; | |
using Orchard.ContentManagement.Records; | |
using Orchard.Data; | |
using Orchard.Environment.Extensions; | |
using Orchard.Utility.Extensions; | |
using Orchard; | |
namespace SchoolPointe.ContentQuery.Services | |
{ | |
public class TestContentQuery : IContentQuery | |
{ | |
private readonly ISessionLocator _sessionLocator; | |
public TestContentQuery(IContentManager contentManager, ISessionLocator sessionLocator) | |
{ | |
_sessionLocator = sessionLocator; | |
ContentManager = contentManager; | |
} | |
public IContentManager ContentManager { get; private set; } | |
IContentQuery<TPart> IContentQuery.ForPart<TPart>() { | |
return new ContentQuery<TPart>(ContentManager, _sessionLocator); | |
} | |
protected class ContentQuery<T> : IContentQuery<T> where T : IContent | |
{ | |
protected readonly ISessionLocator _sessionLocator; | |
protected ISession _session; | |
private IQueryable<ContentItemVersionRecord> _queryable; | |
public ContentQuery(IContentManager contentManager, ISessionLocator sessionLocator) | |
{ | |
ContentManager = contentManager; | |
_sessionLocator = sessionLocator; | |
} | |
public IContentManager ContentManager { get; private set; } | |
protected IQueryable<ContentItemVersionRecord> Queryable | |
{ | |
get { return _queryable ?? (_queryable = BindSession().Linq<ContentItemVersionRecord>()); } | |
set { _queryable = value; } | |
} | |
protected ISession BindSession() | |
{ | |
if (_session == null) | |
_session = _sessionLocator.For(typeof(ContentItemVersionRecord)); | |
return _session; | |
} | |
IContentQuery<TPart> IContentQuery.ForPart<TPart>() | |
{ | |
return new ContentQuery<TPart>(ContentManager, _sessionLocator); | |
} | |
IContentQuery<T> IContentQuery<T>.ForType(params string[] contentTypes) | |
{ | |
Queryable = Queryable.Where(r => contentTypes.Contains(r.ContentItemRecord.ContentType.Name)); | |
return this; | |
} | |
IContentQuery<T> IContentQuery<T>.ForVersion(VersionOptions options) | |
{ | |
if (options == null) | |
Queryable = Queryable.Where(r => r.Published); | |
else if (options.IsPublished) | |
Queryable = Queryable.Where(r => r.Published); | |
else if (options.IsLatest) | |
Queryable = Queryable.Where(r => r.Latest); | |
else if (options.IsDraft) | |
Queryable = Queryable.Where(r => r.Latest && !r.Published); | |
else if (options.IsAllVersions) | |
{ | |
// no-op... all versions will be returned by default | |
} | |
else | |
throw new ApplicationException("Invalid VersionOptions for content query"); | |
return this; | |
} | |
IEnumerable<T> IContentQuery<T>.List() | |
{ | |
return Queryable | |
.AsEnumerable() | |
.Select(x => ContentManager.Get(x.Id, VersionOptions.VersionRecord(x.Id))) | |
.ToReadOnlyCollection() | |
.AsPart<T>(); | |
} | |
IEnumerable<T> IContentQuery<T>.Slice(int skip, int count) | |
{ | |
return Queryable | |
.Skip(skip) | |
.Take(count) | |
.AsEnumerable() | |
.Select(x => ContentManager.Get(x.Id, VersionOptions.VersionRecord(x.Id))) | |
.ToReadOnlyCollection() | |
.AsPart<T>(); | |
} | |
int IContentQuery<T>.Count() | |
{ | |
return Queryable.Count(); | |
} | |
IContentQuery<T, TRecord> IContentQuery<T>.Join<TRecord>() | |
{ | |
return new ContentQuery<T, TRecord>(ContentManager, _sessionLocator, Queryable); | |
} | |
IContentQuery<T, TRecord> IContentQuery<T>.Where<TRecord>(Expression<Func<TRecord, bool>> predicate) | |
{ | |
var newQuery = ((IContentQuery<T, TRecord>)new ContentQuery<T, TRecord>(ContentManager, _sessionLocator, Queryable)); | |
newQuery = newQuery.Where(predicate); | |
return newQuery; | |
} | |
IContentQuery<T, TRecord> IContentQuery<T>.OrderBy<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) | |
{ | |
var newQuery = ((IContentQuery<T, TRecord>)new ContentQuery<T, TRecord>(ContentManager, _sessionLocator, Queryable)); | |
newQuery = newQuery.OrderBy(keySelector); | |
return newQuery; | |
} | |
IContentQuery<T, TRecord> IContentQuery<T>.OrderByDescending<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) | |
{ | |
var newQuery = ((IContentQuery<T, TRecord>)new ContentQuery<T, TRecord>(ContentManager, _sessionLocator, Queryable)); | |
newQuery = newQuery.OrderByDescending(keySelector); | |
return newQuery; | |
} | |
} | |
class ContentQuery<T, TR> : TestContentQuery.ContentQuery<T>, IContentQuery<T, TR> | |
where T : IContent | |
where TR : ContentPartRecord | |
{ | |
private IQueryable<TR> _joinedQuery; | |
public ContentQuery(IContentManager contentManager, ISessionLocator sessionLocator, IQueryable<ContentItemVersionRecord> queryable) | |
: base(contentManager, sessionLocator) | |
{ | |
Queryable = queryable; | |
_joinedQuery = BindSession().Linq<TR>(); | |
} | |
IContentQuery<T, TR> IContentQuery<T, TR>.ForVersion(VersionOptions options) | |
{ | |
if (options == null) | |
Queryable = Queryable.Where(r => r.Published); | |
else if (options.IsPublished) | |
Queryable = Queryable.Where(r => r.Published); | |
else if (options.IsLatest) | |
Queryable = Queryable.Where(r => r.Latest); | |
else if (options.IsDraft) | |
Queryable = Queryable.Where(r => r.Latest && !r.Published); | |
else if (options.IsAllVersions) | |
{ | |
// no-op... all versions will be returned by default | |
} | |
else | |
throw new ApplicationException("Invalid VersionOptions for content query"); | |
return this; | |
} | |
IEnumerable<T> IContentQuery<T>.List() | |
{ | |
Queryable = Queryable.Join( | |
_joinedQuery, | |
rec => rec.Id, | |
trec => trec.Id, | |
(rec, trec) => rec | |
); | |
return Queryable | |
.AsEnumerable() | |
.Select(x => ContentManager.Get(x.Id, VersionOptions.VersionRecord(x.Id))) | |
.ToReadOnlyCollection() | |
.AsPart<T>(); | |
} | |
IEnumerable<T> IContentQuery<T>.Slice(int skip, int count) | |
{ | |
Queryable = Queryable.Join( | |
_joinedQuery, | |
rec => rec.Id, | |
trec => trec.Id, | |
(rec, trec) => rec | |
); | |
return Queryable | |
.Skip(skip) | |
.Take(count) | |
.AsEnumerable() | |
.Select(x => ContentManager.Get(x.Id, VersionOptions.VersionRecord(x.Id))) | |
.ToReadOnlyCollection() | |
.AsPart<T>(); | |
} | |
int IContentQuery<T>.Count() | |
{ | |
return Queryable.Join( | |
_joinedQuery, | |
rec => rec.Id, | |
trec => trec.Id, | |
(rec, trec) => rec | |
).Count(); | |
} | |
IContentQuery<T, TRecord> IContentQuery<T>.Join<TRecord>() | |
{ | |
Queryable = Queryable.Join( | |
_joinedQuery, | |
rec => rec.Id, | |
trec => trec.Id, | |
(rec, trec) => rec | |
); | |
return new ContentQuery<T, TRecord>(ContentManager, _sessionLocator, Queryable); | |
} | |
IContentQuery<T, TR> IContentQuery<T, TR>.Where(Expression<Func<TR, bool>> predicate) | |
{ | |
_joinedQuery = _joinedQuery.Where(predicate); | |
return this; | |
} | |
IContentQuery<T, TR> IContentQuery<T, TR>.OrderBy<TKey>(Expression<Func<TR, TKey>> keySelector) | |
{ | |
_joinedQuery = _joinedQuery.OrderBy(keySelector); | |
return this; | |
} | |
IContentQuery<T, TR> IContentQuery<T, TR>.OrderByDescending<TKey>(Expression<Func<TR, TKey>> keySelector) | |
{ | |
_joinedQuery = _joinedQuery.OrderByDescending(keySelector); | |
return this; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment