Adding strongly typed IContentQuery interfaces

--HG--
extra : convert_revision : svn%3A5ff7c347-ad56-4c35-b696-ccb81de16e03/trunk%4042412
This commit is contained in:
loudej
2009-11-27 04:55:05 +00:00
parent 0c0b49dfc9
commit 3c0f413e34
18 changed files with 195 additions and 85 deletions

View File

@@ -156,8 +156,8 @@ namespace Orchard.Tests.Models {
_manager.Create<Gamma>("gamma", init => { init.Record.Frap = "four"; }); _manager.Create<Gamma>("gamma", init => { init.Record.Frap = "four"; });
_session.Flush(); _session.Flush();
var twoOrFour = _manager.Query() var twoOrFour = _manager.Query<Gamma, GammaRecord>()
.Where<GammaRecord>(x => x.Frap == "one" || x.Frap == "four") .Where(x => x.Frap == "one" || x.Frap == "four")
.List(); .List();
Assert.That(twoOrFour.Count(), Is.EqualTo(2)); Assert.That(twoOrFour.Count(), Is.EqualTo(2));
@@ -170,8 +170,8 @@ namespace Orchard.Tests.Models {
[Test] [Test]
public void EmptyWherePredicateRequiresRecord() { public void EmptyWherePredicateRequiresRecord() {
AddSampleData(); AddSampleData();
var gammas = _manager.Query().Where<GammaRecord>().List(); var gammas = _manager.Query().Join<GammaRecord>().List();
var deltas = _manager.Query().Where<DeltaRecord>().List(); var deltas = _manager.Query().Join<DeltaRecord>().List();
Assert.That(gammas.Count(), Is.EqualTo(1)); Assert.That(gammas.Count(), Is.EqualTo(1));
Assert.That(deltas.Count(), Is.EqualTo(1)); Assert.That(deltas.Count(), Is.EqualTo(1));
@@ -197,9 +197,9 @@ namespace Orchard.Tests.Models {
Assert.That(ascending.Last().Record.Frap, Is.EqualTo("two")); Assert.That(ascending.Last().Record.Frap, Is.EqualTo("two"));
var descending = _manager.Query("gamma") var descending = _manager.Query<Gamma, GammaRecord>()
.OrderByDescending<GammaRecord, string>(x => x.Frap) .OrderByDescending(x => x.Frap)
.List<Gamma>(); .List();
Assert.That(descending.Count(), Is.EqualTo(5)); Assert.That(descending.Count(), Is.EqualTo(5));
Assert.That(descending.First().Record.Frap, Is.EqualTo("two")); Assert.That(descending.First().Record.Frap, Is.EqualTo("two"));
@@ -216,11 +216,11 @@ namespace Orchard.Tests.Models {
_session.Flush(); _session.Flush();
var reverseById = _manager.Query() var reverseById = _manager.Query()
.OrderByDescending<ContentItemRecord, int>(x => x.Id) .OrderByDescending<GammaRecord, int>(x => x.Id)
.List(); .List();
var subset = _manager.Query() var subset = _manager.Query()
.OrderByDescending<ContentItemRecord, int>(x => x.Id) .OrderByDescending<GammaRecord, int>(x => x.Id)
.Slice(2, 3); .Slice(2, 3);
Assert.That(subset.Count(), Is.EqualTo(3)); Assert.That(subset.Count(), Is.EqualTo(3));

View File

@@ -120,7 +120,7 @@ namespace Orchard.Tests.Models {
// create a gamma record // create a gamma record
var gamma = new GammaRecord { var gamma = new GammaRecord {
ContentItem = _container.Resolve<IRepository<ContentItemRecord>>().Get(model.Id), ContentItemRecord = _container.Resolve<IRepository<ContentItemRecord>>().Get(model.Id),
Frap = "foo" Frap = "foo"
}; };
@@ -135,7 +135,7 @@ namespace Orchard.Tests.Models {
Assert.That(model.Id, Is.EqualTo(modelRecord.Id)); Assert.That(model.Id, Is.EqualTo(modelRecord.Id));
Assert.That(model.Is<Gamma>(), Is.True); Assert.That(model.Is<Gamma>(), Is.True);
Assert.That(model.As<Gamma>().Record, Is.Not.Null); Assert.That(model.As<Gamma>().Record, Is.Not.Null);
Assert.That(model.As<Gamma>().Record.ContentItem.Id, Is.EqualTo(model.Id)); Assert.That(model.As<Gamma>().Record.ContentItemRecord.Id, Is.EqualTo(model.Id));
} }

View File

@@ -18,7 +18,7 @@ namespace Orchard.Blogs.Services {
public BlogPost Get(Blog blog, string slug) { public BlogPost Get(Blog blog, string slug) {
RoutableRecord record = RoutableRecord record =
_routableRepository.Get(r => r.ContentItem.ContentType.Name == "blogpost" && r.Slug == slug); _routableRepository.Get(r => r.ContentItemRecord.ContentType.Name == "blogpost" && r.Slug == slug);
BlogPost blogPost = record != null ? _contentManager.Get<BlogPost>(record.Id) : null; BlogPost blogPost = record != null ? _contentManager.Get<BlogPost>(record.Id) : null;
return blogPost != null && blogPost.Record.Blog.Id == blog.ContentItem.Id ? blogPost : null; return blogPost != null && blogPost.Record.Blog.Id == blog.ContentItem.Id ? blogPost : null;
@@ -27,7 +27,7 @@ namespace Orchard.Blogs.Services {
public IEnumerable<BlogPost> Get(Blog blog) { public IEnumerable<BlogPost> Get(Blog blog) {
//TODO: (erikpo) Figure out how to sort by published date //TODO: (erikpo) Figure out how to sort by published date
IEnumerable<RoutableRecord> records = IEnumerable<RoutableRecord> records =
_routableRepository.Fetch(rr => rr.ContentItem.ContentType.Name == "blogpost" _routableRepository.Fetch(rr => rr.ContentItemRecord.ContentType.Name == "blogpost"
/*, bpr => bpr.Asc(bpr2 => bpr2.Published.GetValueOrDefault(new DateTime(2099, 1, 1)))*/); /*, bpr => bpr.Asc(bpr2 => bpr2.Published.GetValueOrDefault(new DateTime(2099, 1, 1)))*/);
//TODO: (erikpo) Need to filter by blog in the line above instead of filtering here //TODO: (erikpo) Need to filter by blog in the line above instead of filtering here

View File

@@ -17,13 +17,13 @@ namespace Orchard.Blogs.Services {
} }
public Blog Get(string slug) { public Blog Get(string slug) {
RoutableRecord record = _routableRepository.Get(r => r.ContentItem.ContentType.Name == "blog" && r.Slug == slug); RoutableRecord record = _routableRepository.Get(r => r.ContentItemRecord.ContentType.Name == "blog" && r.Slug == slug);
return record != null ?_contentManager.Get<Blog>(record.Id) : null; return record != null ?_contentManager.Get<Blog>(record.Id) : null;
} }
public IEnumerable<Blog> Get() { public IEnumerable<Blog> Get() {
IEnumerable<RoutableRecord> records = _routableRepository.Fetch(rr => rr.ContentItem.ContentType.Name == "blog", rr => rr.Asc(rr2 => rr2.Title)); IEnumerable<RoutableRecord> records = _routableRepository.Fetch(rr => rr.ContentItemRecord.ContentType.Name == "blog", rr => rr.Asc(rr2 => rr2.Title));
return records.Select(rr => _contentManager.Get<Blog>(rr.Id)); return records.Select(rr => _contentManager.Get<Blog>(rr.Id));
} }

View File

@@ -26,7 +26,7 @@ namespace Orchard.DevTools.Controllers {
public ActionResult Index() { public ActionResult Index() {
return View(new ContentIndexViewModel { return View(new ContentIndexViewModel {
Items = _contentManager.Query().OrderBy<ContentItemRecord, int>(x => x.Id).List(), Items = _contentManager.Query().List(),
Types = _contentTypeRepository.Table.ToList() Types = _contentTypeRepository.Table.ToList()
}); });
} }

View File

@@ -29,18 +29,19 @@ namespace Orchard.Sandbox.Controllers {
public ActionResult Index() { public ActionResult Index() {
var model = new PageIndexViewModel { var model = new PageIndexViewModel {
Pages = _contentManager.Query() Pages = _contentManager.Query<SandboxPage, SandboxPageRecord>()
.OrderBy<SandboxPageRecord, string>(x => x.Name) .OrderBy(x => x.Name)
.List<SandboxPage>() .List()
}; };
return View(model); return View(model);
} }
public ActionResult Show(int id) { public ActionResult Show(int id) {
var page = _contentManager.Get<SandboxPage>(id);
var model = new PageShowViewModel { var model = new PageShowViewModel {
Page = _contentManager.Get<SandboxPage>(id) Page = page,
Displays = _contentManager.GetDisplays(page)
}; };
model.Displays = _contentManager.GetDisplays(model.Page.ContentItem);
return View(model); return View(model);
} }
@@ -74,7 +75,7 @@ namespace Orchard.Sandbox.Controllers {
var settings = CurrentSite.Get<ContentPart<SandboxSettingsRecord>>(); var settings = CurrentSite.Get<ContentPart<SandboxSettingsRecord>>();
if (settings.Record.AllowAnonymousEdits == false && CurrentUser == null) { if (settings.Record.AllowAnonymousEdits == false && CurrentUser == null) {
_notifier.Error(T("Anonymous users can not edit pages")); _notifier.Error(T("Anonymous users can not edit pages"));
return RedirectToAction("show", new{id}); return RedirectToAction("show", new { id });
} }
var model = new PageEditViewModel { Page = _contentManager.Get<SandboxPage>(id) }; var model = new PageEditViewModel { Page = _contentManager.Get<SandboxPage>(id) };

View File

@@ -37,9 +37,9 @@ namespace Orchard.Users.Controllers {
public ActionResult Index() { public ActionResult Index() {
var model = new UsersIndexViewModel(); var model = new UsersIndexViewModel();
var users = _contentManager.Query("user") var users = _contentManager.Query<User,UserRecord>("user")
.Where<UserRecord>(x => x.UserName != null) .Where(x => x.UserName != null)
.List<User>(); .List();
model.Rows = users.Select(x => new UsersIndexViewModel.Row {User = x}).ToList(); model.Rows = users.Select(x => new UsersIndexViewModel.Row {User = x}).ToList();

View File

@@ -63,7 +63,7 @@ namespace Orchard.Environment {
(type.GetProperty("Id").GetAccessors() ?? Enumerable.Empty<MethodInfo>()).All(x => x.IsVirtual) && (type.GetProperty("Id").GetAccessors() ?? Enumerable.Empty<MethodInfo>()).All(x => x.IsVirtual) &&
!type.IsSealed && !type.IsSealed &&
!type.IsAbstract && !type.IsAbstract &&
!typeof(IContent).IsAssignableFrom(type); (!typeof(IContent).IsAssignableFrom(type) || typeof(ContentPartRecord).IsAssignableFrom(type));
} }
} }
} }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Orchard.Models.Records;
namespace Orchard.Models { namespace Orchard.Models {
@@ -33,23 +34,37 @@ namespace Orchard.Models {
} }
public static IContentQuery Query(this IContentManager manager, params string[] contentTypeNames) { public static IContentQuery<TPart> Query<TPart>(this IContentManager manager)
return manager.Query().ForType(contentTypeNames); where TPart : ContentPart {
return manager.Query().ForPart<TPart>();
} }
public static IEnumerable<T> List<T>(this IContentManager manager, params string[] contentTypeNames) where T : class, IContent { public static IContentQuery<TPart, TRecord> Query<TPart, TRecord>(this IContentManager manager)
return manager.Query(contentTypeNames).List<T>(); where TPart : ContentPart<TRecord>
where TRecord : ContentPartRecord {
return manager.Query().ForPart<TPart>().Join<TRecord>();
} }
public static IEnumerable<T> List<T>(this IContentQuery query) where T : class, IContent { public static IContentQuery<ContentItem> Query(this IContentManager manager, params string[] contentTypeNames) {
return query.List().AsPart<T>(); return manager.Query().ForType(contentTypeNames);
} }
public static IEnumerable<T> Slice<T>(this IContentQuery query, int skip, int count) where T : class, IContent { public static IContentQuery<TPart> Query<TPart>(this IContentManager manager, params string[] contentTypeNames) where TPart : ContentPart {
return query.Slice(skip, count).AsPart<T>(); return manager.Query().ForPart<TPart>().ForType(contentTypeNames);
} }
public static IEnumerable<T> Slice<T>(this IContentQuery query, int count) where T : class, IContent { public static IContentQuery<TPart,TRecord> Query<TPart,TRecord>(this IContentManager manager, params string[] contentTypeNames) where TPart : ContentPart<TRecord> where TRecord : ContentPartRecord {
return query.Slice(0, count).AsPart<T>(); return manager.Query().ForPart<TPart>().ForType(contentTypeNames).Join<TRecord>();
} }
public static IEnumerable<ContentItem> Slice(this IContentQuery query, int count) {
public static IEnumerable<T> List<T>(this IContentManager manager, params string[] contentTypeNames) where T : ContentPart {
return manager.Query<T>(contentTypeNames).List();
}
public static IEnumerable<T> List<T>(this IContentQuery query) where T : IContent {
return query.ForPart<T>().List();
}
public static IEnumerable<T> Slice<T>(this IContentQuery<T> query, int count) where T : IContent {
return query.Slice(0, count); return query.Slice(0, count);
} }
@@ -58,19 +73,19 @@ namespace Orchard.Models {
public static bool Is<T>(this IContent content) { public static bool Is<T>(this IContent content) {
return content == null ? false : content.ContentItem.Has(typeof(T)); return content == null ? false : content.ContentItem.Has(typeof(T));
} }
public static T As<T>(this IContent content) where T : class { public static T As<T>(this IContent content) where T : IContent {
return content == null ? null : (T)content.ContentItem.Get(typeof(T)); return content == null ? default(T) : (T)content.ContentItem.Get(typeof(T));
} }
public static bool Has<T>(this IContent content) { public static bool Has<T>(this IContent content) {
return content == null ? false : content.ContentItem.Has(typeof(T)); return content == null ? false : content.ContentItem.Has(typeof(T));
} }
public static T Get<T>(this IContent content) where T : class { public static T Get<T>(this IContent content) where T : IContent {
return content == null ? null : (T)content.ContentItem.Get(typeof(T)); return content == null ? default(T) : (T)content.ContentItem.Get(typeof(T));
} }
public static IEnumerable<T> AsPart<T>(this IEnumerable<ContentItem> items) where T : class { public static IEnumerable<T> AsPart<T>(this IEnumerable<ContentItem> items) where T : IContent {
return items == null ? null : items.Where(item => item.Is<T>()).Select(item => item.As<T>()); return items == null ? null : items.Where(item => item.Is<T>()).Select(item => item.As<T>());
} }

View File

@@ -21,10 +21,12 @@ namespace Orchard.Models {
public bool Has(Type partType) { public bool Has(Type partType) {
return _parts.Any(part => partType.IsAssignableFrom(part.GetType())); return partType==typeof(ContentItem) || _parts.Any(part => partType.IsAssignableFrom(part.GetType()));
} }
public IContent Get(Type partType) { public IContent Get(Type partType) {
if (partType == typeof(ContentItem))
return this;
return _parts.FirstOrDefault(part => partType.IsAssignableFrom(part.GetType())); return _parts.FirstOrDefault(part => partType.IsAssignableFrom(part.GetType()));
} }

View File

@@ -1,6 +1,6 @@
namespace Orchard.Models { namespace Orchard.Models {
public abstract class ContentPart : IContent { public abstract class ContentPart : IContent {
public ContentItem ContentItem { get; set; } public virtual ContentItem ContentItem { get; set; }
} }
public class ContentPart<TRecord> : ContentPart { public class ContentPart<TRecord> : ContentPart {

View File

@@ -139,8 +139,9 @@ namespace Orchard.Models {
return context.Editors; return context.Editors;
} }
public IContentQuery Query() { public IContentQuery<ContentItem> Query() {
return _context.Resolve<IContentQuery>(TypedParameter.From<IContentManager>(this)); var query = _context.Resolve<IContentQuery>(TypedParameter.From<IContentManager>(this));
return query.ForPart<ContentItem>();
} }
private ContentTypeRecord AcquireContentTypeRecord(string contentType) { private ContentTypeRecord AcquireContentTypeRecord(string contentType) {

View File

@@ -46,19 +46,19 @@ namespace Orchard.Models {
} }
public IContentQuery ForType(params string[] contentTypeNames) { private void ForType(params string[] contentTypeNames) {
BindCriteriaByPath("ContentType").Add(Restrictions.InG("Name", contentTypeNames)); BindCriteriaByPath("ContentType").Add(Restrictions.InG("Name", contentTypeNames));
return this; return;
} }
public IContentQuery Where<TRecord>() { private void Where<TRecord>() {
// this simply demands an inner join // this simply demands an inner join
BindCriteriaByPath(typeof(TRecord).Name); BindCriteriaByPath(typeof(TRecord).Name);
return this; return;
} }
public IContentQuery Where<TRecord>(Expression<Func<TRecord, bool>> predicate) { private void Where<TRecord>(Expression<Func<TRecord, bool>> predicate) {
// build a linq to nhibernate expression // build a linq to nhibernate expression
var options = new QueryOptions(); var options = new QueryOptions();
@@ -74,10 +74,10 @@ namespace Orchard.Models {
recordCriteria.Add(expressionEntry.Criterion); recordCriteria.Add(expressionEntry.Criterion);
} }
return this; return;
} }
public IContentQuery OrderBy<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) { private void OrderBy<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) {
// build a linq to nhibernate expression // build a linq to nhibernate expression
var options = new QueryOptions(); var options = new QueryOptions();
var queryProvider = new NHibernateQueryProvider(BindSession(), options); var queryProvider = new NHibernateQueryProvider(BindSession(), options);
@@ -92,10 +92,10 @@ namespace Orchard.Models {
recordCriteria.AddOrder(ordering.Order); recordCriteria.AddOrder(ordering.Order);
} }
return this; return;
} }
public IContentQuery OrderByDescending<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) { private void OrderByDescending<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) {
// build a linq to nhibernate expression // build a linq to nhibernate expression
var options = new QueryOptions(); var options = new QueryOptions();
var queryProvider = new NHibernateQueryProvider(BindSession(), options); var queryProvider = new NHibernateQueryProvider(BindSession(), options);
@@ -109,16 +109,16 @@ namespace Orchard.Models {
foreach (var ordering in criteria.IterateOrderings()) { foreach (var ordering in criteria.IterateOrderings()) {
recordCriteria.AddOrder(ordering.Order); recordCriteria.AddOrder(ordering.Order);
} }
return this; return;
} }
public IEnumerable<ContentItem> List() { private IEnumerable<ContentItem> List() {
return BindItemCriteria() return BindItemCriteria()
.List<ContentItemRecord>() .List<ContentItemRecord>()
.Select(x => ContentManager.Get(x.Id)); .Select(x => ContentManager.Get(x.Id));
} }
public IEnumerable<ContentItem> Slice(int skip, int count) { private IEnumerable<ContentItem> Slice(int skip, int count) {
var criteria = BindItemCriteria(); var criteria = BindItemCriteria();
if (skip != 0) if (skip != 0)
criteria = criteria.SetFirstResult(skip); criteria = criteria.SetFirstResult(skip);
@@ -128,5 +128,82 @@ namespace Orchard.Models {
.List<ContentItemRecord>() .List<ContentItemRecord>()
.Select(x => ContentManager.Get(x.Id)); .Select(x => ContentManager.Get(x.Id));
} }
}
IContentQuery<TPart> IContentQuery.ForPart<TPart>() {
return new ContentQuery<TPart>(this);
}
class ContentQuery<T> : IContentQuery<T> where T : IContent {
protected readonly DefaultContentQuery _query;
public ContentQuery(DefaultContentQuery query) {
_query = query;
}
public IContentManager ContentManager {
get { return _query.ContentManager; }
}
public IContentQuery<TPart> ForPart<TPart>() where TPart : IContent {
return new ContentQuery<TPart>(_query);
}
public IContentQuery<T> ForType(params string[] contentTypes) {
_query.ForType(contentTypes);
return this;
}
public IEnumerable<T> List() {
return _query.List().AsPart<T>();
}
public IEnumerable<T> Slice(int skip, int count) {
return _query.Slice(skip, count).AsPart<T>();
}
public IContentQuery<T, TRecord> Join<TRecord>() where TRecord : ContentPartRecord {
_query.Where<TRecord>();
return new ContentQuery<T, TRecord>(_query);
}
public IContentQuery<T, TRecord> Where<TRecord>(Expression<Func<TRecord, bool>> predicate) where TRecord : ContentPartRecord {
_query.Where(predicate);
return new ContentQuery<T, TRecord>(_query);
}
public IContentQuery<T, TRecord> OrderBy<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) where TRecord : ContentPartRecord {
_query.OrderBy(keySelector);
return new ContentQuery<T, TRecord>(_query);
}
public IContentQuery<T, TRecord> OrderByDescending<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) where TRecord : ContentPartRecord {
_query.OrderByDescending(keySelector);
return new ContentQuery<T, TRecord>(_query);
}
}
class ContentQuery<T, TR> : ContentQuery<T>, IContentQuery<T, TR>
where T : IContent
where TR : ContentPartRecord {
public ContentQuery(DefaultContentQuery query)
: base(query) {
}
public IContentQuery<T, TR> Where(Expression<Func<TR, bool>> predicate) {
_query.Where(predicate);
return this;
}
public IContentQuery<T, TR> OrderBy<TKey>(Expression<Func<TR, TKey>> keySelector) {
_query.OrderBy(keySelector);
return this;
}
public IContentQuery<T, TR> OrderByDescending<TKey>(Expression<Func<TR, TKey>> keySelector) {
_query.OrderByDescending(keySelector);
return this;
}
}
}
} }

View File

@@ -16,7 +16,7 @@ namespace Orchard.Models.Driver {
} }
protected override void Creating(CreateContentContext context, ContentPart<TRecord> instance) { protected override void Creating(CreateContentContext context, ContentPart<TRecord> instance) {
instance.Record.ContentItem = context.ContentItemRecord; instance.Record.ContentItemRecord = context.ContentItemRecord;
_repository.Create(instance.Record); _repository.Create(instance.Record);
} }
@@ -26,7 +26,7 @@ namespace Orchard.Models.Driver {
instance.Record = record; instance.Record = record;
} }
else if (AutomaticallyCreateMissingRecord) { else if (AutomaticallyCreateMissingRecord) {
instance.Record = new TRecord {ContentItem = context.ContentItemRecord}; instance.Record = new TRecord {ContentItemRecord = context.ContentItemRecord};
_repository.Create(instance.Record); _repository.Create(instance.Record);
} }
} }

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using Orchard.Models.Driver; using Orchard.Models.Driver;
using Orchard.Models.Records;
using Orchard.UI.Models; using Orchard.UI.Models;
namespace Orchard.Models { namespace Orchard.Models {
@@ -8,7 +9,8 @@ namespace Orchard.Models {
void Create(ContentItem contentItem); void Create(ContentItem contentItem);
ContentItem Get(int id); ContentItem Get(int id);
IContentQuery Query();
IContentQuery<ContentItem> Query();
IEnumerable<ModelTemplate> GetDisplays(IContent contentItem); IEnumerable<ModelTemplate> GetDisplays(IContent contentItem);
IEnumerable<ModelTemplate> GetEditors(IContent contentItem); IEnumerable<ModelTemplate> GetEditors(IContent contentItem);

View File

@@ -1,20 +1,31 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq.Expressions; using System.Linq.Expressions;
using Orchard.Models.Records;
namespace Orchard.Models { namespace Orchard.Models {
public interface IContentQuery { public interface IContentQuery {
IContentManager ContentManager { get; } IContentManager ContentManager { get; }
IContentQuery<TPart> ForPart<TPart>() where TPart : IContent;
IContentQuery ForType(params string[] contentTypeNames);
IContentQuery Where<TRecord>();
IContentQuery Where<TRecord>(Expression<Func<TRecord, bool>> predicate);
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);
} }
public interface IContentQuery<TPart> : IContentQuery where TPart : IContent {
IContentQuery<TPart> ForType(params string[] contentTypes);
IEnumerable<TPart> List();
IEnumerable<TPart> Slice(int skip, int count);
IContentQuery<TPart, TRecord> Join<TRecord>() where TRecord : ContentPartRecord;
IContentQuery<TPart, TRecord> Where<TRecord>(Expression<Func<TRecord, bool>> predicate) where TRecord : ContentPartRecord;
IContentQuery<TPart, TRecord> OrderBy<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) where TRecord : ContentPartRecord;
IContentQuery<TPart, TRecord> OrderByDescending<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) where TRecord : ContentPartRecord;
}
public interface IContentQuery<TPart, TRecord> : IContentQuery<TPart> where TPart : IContent where TRecord : ContentPartRecord {
IContentQuery<TPart, TRecord> Where(Expression<Func<TRecord, bool>> predicate);
IContentQuery<TPart, TRecord> OrderBy<TKey>(Expression<Func<TRecord, TKey>> keySelector);
IContentQuery<TPart, TRecord> OrderByDescending<TKey>(Expression<Func<TRecord, TKey>> keySelector);
}
} }

View File

@@ -1,6 +1,6 @@
namespace Orchard.Models.Records { namespace Orchard.Models.Records {
public abstract class ContentPartRecord { public abstract class ContentPartRecord : ContentPart {
public virtual int Id { get; set; } public virtual int Id { get; set; }
public virtual ContentItemRecord ContentItem { get; set; } public virtual ContentItemRecord ContentItemRecord { get; set; }
} }
} }

View File

@@ -8,15 +8,15 @@ namespace Orchard.Models.Records {
public void Alter(AutoPersistenceModel model) { public void Alter(AutoPersistenceModel model) {
model.OverrideAll(mapping => { model.OverrideAll(mapping => {
var genericArguments = mapping.GetType().GetGenericArguments(); var genericArguments = mapping.GetType().GetGenericArguments();
if (!genericArguments.Single().IsSubclassOf(typeof(ContentPartRecord))) { if (!genericArguments.Single().IsSubclassOf(typeof(ContentPartRecord))) {
return; return;
} }
var type = typeof(Alteration<>).MakeGenericType(genericArguments); var type = typeof(Alteration<>).MakeGenericType(genericArguments);
var alteration = (IAlteration)Activator.CreateInstance(type); var alteration = (IAlteration)Activator.CreateInstance(type);
alteration.Override(mapping); alteration.Override(mapping);
}); });
} }
@@ -27,8 +27,9 @@ namespace Orchard.Models.Records {
class Alteration<T> : IAlteration where T : ContentPartRecord { class Alteration<T> : IAlteration where T : ContentPartRecord {
public void Override(object mappingObj) { public void Override(object mappingObj) {
var mapping = (AutoMapping<T>)mappingObj; var mapping = (AutoMapping<T>)mappingObj;
mapping.Id(x => x.Id).GeneratedBy.Foreign("ContentItem"); mapping.Id(x => x.Id).GeneratedBy.Foreign("ContentItemRecord");
mapping.HasOne(x => x.ContentItem).Constrained(); mapping.HasOne(x => x.ContentItemRecord).Constrained();
mapping.IgnoreProperty(x => x.ContentItem);
} }
} }
} }