mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Implementing dynamic query operators
--HG-- branch : 1.x
This commit is contained in:
233
src/Orchard.Tests/ContentManagement/DynamicContentQueryTests.cs
Normal file
233
src/Orchard.Tests/ContentManagement/DynamicContentQueryTests.cs
Normal file
@@ -0,0 +1,233 @@
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using Moq;
|
||||
using NHibernate;
|
||||
using NUnit.Framework;
|
||||
using Orchard.ContentManagement.MetaData;
|
||||
using Orchard.Data;
|
||||
using Orchard.ContentManagement;
|
||||
using Orchard.ContentManagement.Handlers;
|
||||
using Orchard.ContentManagement.Records;
|
||||
using Orchard.DisplayManagement;
|
||||
using Orchard.DisplayManagement.Descriptors;
|
||||
using Orchard.Environment.Extensions;
|
||||
using Orchard.Tests.ContentManagement.Handlers;
|
||||
using Orchard.Tests.ContentManagement.Records;
|
||||
using Orchard.Tests.ContentManagement.Models;
|
||||
using Orchard.DisplayManagement.Implementation;
|
||||
using Orchard.Tests.Stubs;
|
||||
|
||||
namespace Orchard.Tests.ContentManagement {
|
||||
[TestFixture]
|
||||
public class DynamicContentQueryTests {
|
||||
private IContainer _container;
|
||||
private IContentManager _manager;
|
||||
private ISessionFactory _sessionFactory;
|
||||
private ISession _session;
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void InitFixture() {
|
||||
var databaseFileName = System.IO.Path.GetTempFileName();
|
||||
_sessionFactory = DataUtility.CreateSessionFactory(
|
||||
databaseFileName,
|
||||
typeof(GammaRecord),
|
||||
typeof(DeltaRecord),
|
||||
typeof(EpsilonRecord),
|
||||
typeof(ContentItemVersionRecord),
|
||||
typeof(ContentItemRecord),
|
||||
typeof(ContentTypeRecord));
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Init() {
|
||||
var builder = new ContainerBuilder();
|
||||
|
||||
builder.RegisterModule(new ContentModule());
|
||||
builder.RegisterType<DefaultContentManager>().As<IContentManager>().SingleInstance();
|
||||
builder.RegisterType<DefaultContentManagerSession>().As<IContentManagerSession>();
|
||||
builder.RegisterInstance(new Mock<IContentDefinitionManager>().Object);
|
||||
builder.RegisterInstance(new Mock<IContentDisplay>().Object);
|
||||
|
||||
builder.RegisterType<AlphaPartHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<BetaPartHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<GammaPartHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<DeltaPartHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<EpsilonPartHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<FlavoredPartHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<StyledHandler>().As<IContentHandler>();
|
||||
builder.RegisterType<DefaultShapeTableManager>().As<IShapeTableManager>();
|
||||
builder.RegisterType<ShapeTableLocator>().As<IShapeTableLocator>();
|
||||
builder.RegisterType<DefaultShapeFactory>().As<IShapeFactory>();
|
||||
|
||||
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
|
||||
|
||||
builder.RegisterType<StubExtensionManager>().As<IExtensionManager>();
|
||||
builder.RegisterType<DefaultContentDisplay>().As<IContentDisplay>();
|
||||
|
||||
_session = _sessionFactory.OpenSession();
|
||||
builder.RegisterInstance(new DefaultContentManagerTests.TestSessionLocator(_session)).As<ISessionLocator>();
|
||||
|
||||
_session.Delete(string.Format("from {0}", typeof(GammaRecord).FullName));
|
||||
_session.Delete(string.Format("from {0}", typeof(DeltaRecord).FullName));
|
||||
_session.Delete(string.Format("from {0}", typeof(EpsilonRecord).FullName));
|
||||
_session.Delete(string.Format("from {0}", typeof(ContentItemVersionRecord).FullName));
|
||||
_session.Delete(string.Format("from {0}", typeof(ContentItemRecord).FullName));
|
||||
_session.Delete(string.Format("from {0}", typeof(ContentTypeRecord).FullName));
|
||||
_session.Flush();
|
||||
_session.Clear();
|
||||
|
||||
_container = builder.Build();
|
||||
_manager = _container.Resolve<IContentManager>();
|
||||
|
||||
}
|
||||
|
||||
private void AddSampleData() {
|
||||
_manager.Create<AlphaPart>("alpha", init => { });
|
||||
_manager.Create<BetaPart>("beta", init => { });
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "the frap value"; });
|
||||
_manager.Create<DeltaPart>("delta", init => { init.Record.Quux = "the quux value"; });
|
||||
_session.Flush();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SpecificTypeIsReturnedWhenSpecified() {
|
||||
AddSampleData();
|
||||
|
||||
var alphaBeta = _manager.Query().Where(x => x.WithRecord("ContentType").In("Name", new [] {"alpha", "beta"})).List();
|
||||
|
||||
Assert.That(alphaBeta.Count(), Is.EqualTo(2));
|
||||
Assert.That(alphaBeta.Count(x => x.Has<AlphaPart>()), Is.EqualTo(1));
|
||||
Assert.That(alphaBeta.Count(x => x.Has<BetaPart>()), Is.EqualTo(1));
|
||||
Assert.That(alphaBeta.Count(x => x.Has<GammaPart>()), Is.EqualTo(0));
|
||||
Assert.That(alphaBeta.Count(x => x.Has<DeltaPart>()), Is.EqualTo(0));
|
||||
|
||||
var gammaDelta = _manager.Query().Where(x => x.WithRecord("ContentType").In("Name", new[] { "gamma", "delta" })).List();
|
||||
|
||||
Assert.That(gammaDelta.Count(), Is.EqualTo(2));
|
||||
Assert.That(gammaDelta.Count(x => x.Has<AlphaPart>()), Is.EqualTo(0));
|
||||
Assert.That(gammaDelta.Count(x => x.Has<BetaPart>()), Is.EqualTo(0));
|
||||
Assert.That(gammaDelta.Count(x => x.Has<GammaPart>()), Is.EqualTo(1));
|
||||
Assert.That(gammaDelta.Count(x => x.Has<DeltaPart>()), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WherePredicateRestrictsResults() {
|
||||
AddSampleData();
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "one"; });
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "two"; });
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "three"; });
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "four"; });
|
||||
_session.Flush();
|
||||
|
||||
var twoOrFour = _manager.Query<GammaPart, GammaRecord>()
|
||||
.Where(x => x.WithRecord("GammaRecord").Or(a => a.Eq("Frap", "one"), b => b.Eq("Frap", "four")))
|
||||
.List();
|
||||
|
||||
Assert.That(twoOrFour.Count(), Is.EqualTo(2));
|
||||
Assert.That(twoOrFour.Count(x => x.Has<GammaPart>()), Is.EqualTo(2));
|
||||
Assert.That(twoOrFour.Count(x => x.Get<GammaPart>().Record.Frap == "one"), Is.EqualTo(1));
|
||||
Assert.That(twoOrFour.Count(x => x.Get<GammaPart>().Record.Frap == "four"), Is.EqualTo(1));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void EmptyWherePredicateRequiresRecord() {
|
||||
AddSampleData();
|
||||
var gammas = _manager.Query().Where(x => x.WithRecord("GammaRecord")).List(); // simulates an inner join
|
||||
var deltas = _manager.Query().Where(x => x.WithRecord("DeltaRecord")).List();
|
||||
|
||||
Assert.That(gammas.Count(), Is.EqualTo(1));
|
||||
Assert.That(deltas.Count(), Is.EqualTo(1));
|
||||
Assert.That(gammas.AsPart<GammaPart>().Single().Record.Frap, Is.EqualTo("the frap value"));
|
||||
Assert.That(deltas.AsPart<DeltaPart>().Single().Record.Quux, Is.EqualTo("the quux value"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void OrderMaySortOnJoinedRecord() {
|
||||
AddSampleData();
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "one"; });
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "two"; });
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "three"; });
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "four"; });
|
||||
_session.Flush();
|
||||
_session.Clear();
|
||||
|
||||
var ascending = _manager.Query("gamma")
|
||||
.OrderBy(x => x.WithRecord("GammaRecord").Asc("Frap"))
|
||||
.List<GammaPart>().ToList();
|
||||
|
||||
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"));
|
||||
|
||||
_session.Clear();
|
||||
|
||||
var descending = _manager.Query<GammaPart, GammaRecord>()
|
||||
.OrderBy(x => x.WithRecord("GammaRecord").Desc("Frap"))
|
||||
.List().ToList();
|
||||
|
||||
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<GammaPart>("gamma", init => { init.Record.Frap = "one"; });
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "two"; });
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "three"; });
|
||||
_manager.Create<GammaPart>("gamma", init => { init.Record.Frap = "four"; });
|
||||
_session.Flush();
|
||||
|
||||
var reverseById = _manager.Query()
|
||||
.OrderBy(x => x.WithRecord("GammaRecord").Desc("Id"))
|
||||
.List();
|
||||
|
||||
var subset = _manager.Query()
|
||||
.OrderBy(x => x.WithRecord("GammaRecord").Desc("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));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void QueryShouldJoinVersionedRecords() {
|
||||
AddSampleData();
|
||||
_manager.Create<GammaPart>("gamma", init => {
|
||||
init.Record.Frap = "one";
|
||||
init.As<EpsilonPart>().Record.Quad = "1";
|
||||
});
|
||||
_manager.Create<GammaPart>("gamma", init => {
|
||||
init.Record.Frap = "two";
|
||||
init.As<EpsilonPart>().Record.Quad = "2";
|
||||
});
|
||||
_manager.Create<GammaPart>("gamma", init => {
|
||||
init.Record.Frap = "three";
|
||||
init.As<EpsilonPart>().Record.Quad = "3";
|
||||
});
|
||||
_manager.Create<GammaPart>("gamma", init => {
|
||||
init.Record.Frap = "four";
|
||||
init.As<EpsilonPart>().Record.Quad = "4";
|
||||
});
|
||||
_session.Flush();
|
||||
_session.Clear();
|
||||
|
||||
var results = _manager.Query("gamma")
|
||||
.Where(x => x.WithVersionRecord("EpsilonRecord").Or(a => a.Eq("Quad", "2"), b => b.Eq("Quad", "3")))
|
||||
.OrderBy(x => x.WithVersionRecord("EpsilonRecord").Desc("Quad"))
|
||||
.List<EpsilonPart>();
|
||||
|
||||
Assert.That(results.Count(), Is.EqualTo(2));
|
||||
Assert.That(results.First().Record, Has.Property("Quad").EqualTo("3"));
|
||||
Assert.That(results.Last().Record, Has.Property("Quad").EqualTo("2"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ContentManagement\ContentQueryTests.cs" />
|
||||
<Compile Include="ContentManagement\DynamicContentQueryTests.cs" />
|
||||
<Compile Include="ContentManagement\DefaultContentManagerTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
@@ -30,37 +31,36 @@ namespace Orchard.ContentManagement {
|
||||
return _session;
|
||||
}
|
||||
|
||||
ICriteria BindCriteriaByPath(ICriteria criteria, string path) {
|
||||
internal ICriteria BindCriteriaByPath(ICriteria criteria, string path) {
|
||||
return criteria.GetCriteriaByPath(path) ?? criteria.CreateCriteria(path);
|
||||
}
|
||||
|
||||
ICriteria BindTypeCriteria() {
|
||||
internal ICriteria BindTypeCriteria() {
|
||||
// ([ContentItemVersionRecord] >join> [ContentItemRecord]) >join> [ContentType]
|
||||
|
||||
return BindCriteriaByPath(BindItemCriteria(), "ContentType");
|
||||
}
|
||||
|
||||
ICriteria BindItemCriteria() {
|
||||
internal ICriteria BindItemCriteria() {
|
||||
// [ContentItemVersionRecord] >join> [ContentItemRecord]
|
||||
|
||||
return BindCriteriaByPath(BindItemVersionCriteria(), "ContentItemRecord");
|
||||
}
|
||||
|
||||
ICriteria BindItemVersionCriteria() {
|
||||
internal ICriteria BindItemVersionCriteria() {
|
||||
if (_itemVersionCriteria == null) {
|
||||
_itemVersionCriteria = BindSession().CreateCriteria<ContentItemVersionRecord>();
|
||||
}
|
||||
return _itemVersionCriteria;
|
||||
}
|
||||
|
||||
ICriteria BindPartCriteria<TRecord>() where TRecord : ContentPartRecord {
|
||||
internal ICriteria BindPartCriteria<TRecord>() where TRecord : ContentPartRecord {
|
||||
if (typeof(TRecord).IsSubclassOf(typeof(ContentPartVersionRecord))) {
|
||||
return BindCriteriaByPath(BindItemVersionCriteria(), typeof(TRecord).Name);
|
||||
}
|
||||
return BindCriteriaByPath(BindItemCriteria(), typeof(TRecord).Name);
|
||||
}
|
||||
|
||||
|
||||
private void ForType(params string[] contentTypeNames) {
|
||||
if (contentTypeNames != null && contentTypeNames.Length != 0)
|
||||
BindTypeCriteria().Add(Restrictions.InG("Name", contentTypeNames));
|
||||
@@ -92,6 +92,15 @@ namespace Orchard.ContentManagement {
|
||||
}
|
||||
}
|
||||
|
||||
private void Where(Action<IExpressionFactory> expression) {
|
||||
var expressionFactory = new DefaultExpressionFactory(this);
|
||||
|
||||
expression(expressionFactory);
|
||||
if (expressionFactory.Criterion != null) {
|
||||
expressionFactory.Criteria.Add(expressionFactory.Criterion);
|
||||
}
|
||||
}
|
||||
|
||||
private void OrderBy<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) where TRecord : ContentPartRecord {
|
||||
// build a linq to nhibernate expression
|
||||
var options = new QueryOptions();
|
||||
@@ -108,6 +117,15 @@ namespace Orchard.ContentManagement {
|
||||
}
|
||||
}
|
||||
|
||||
private void OrderBy(Action<ISortFactory> expression) {
|
||||
var sortFactory = new DefaultSortFactory(this);
|
||||
|
||||
expression(sortFactory);
|
||||
if (sortFactory.Order != null) {
|
||||
sortFactory.Criteria.AddOrder(sortFactory.Order);
|
||||
}
|
||||
}
|
||||
|
||||
private void OrderByDescending<TRecord, TKey>(Expression<Func<TRecord, TKey>> keySelector) where TRecord : ContentPartRecord {
|
||||
// build a linq to nhibernate expression
|
||||
var options = new QueryOptions();
|
||||
@@ -126,7 +144,7 @@ namespace Orchard.ContentManagement {
|
||||
|
||||
private IEnumerable<ContentItem> Slice(int skip, int count) {
|
||||
var criteria = BindItemVersionCriteria();
|
||||
|
||||
|
||||
criteria.ApplyVersionOptionsRestrictions(_versionOptions);
|
||||
|
||||
// TODO: put 'removed false' filter in place
|
||||
@@ -197,6 +215,11 @@ namespace Orchard.ContentManagement {
|
||||
return new ContentQuery<T, TRecord>(_query);
|
||||
}
|
||||
|
||||
IContentQuery<T> IContentQuery<T>.Where(Action<IExpressionFactory> predicate) {
|
||||
_query.Where(predicate);
|
||||
return new ContentQuery<T>(_query);
|
||||
}
|
||||
|
||||
IContentQuery<T, TRecord> IContentQuery<T>.Where<TRecord>(Expression<Func<TRecord, bool>> predicate) {
|
||||
_query.Where(predicate);
|
||||
return new ContentQuery<T, TRecord>(_query);
|
||||
@@ -211,8 +234,12 @@ namespace Orchard.ContentManagement {
|
||||
_query.OrderByDescending(keySelector);
|
||||
return new ContentQuery<T, TRecord>(_query);
|
||||
}
|
||||
}
|
||||
|
||||
IContentQuery<T> IContentQuery<T>.OrderBy(Action<ISortFactory> order) {
|
||||
_query.OrderBy(order);
|
||||
return new ContentQuery<T>(_query);
|
||||
}
|
||||
}
|
||||
|
||||
class ContentQuery<T, TR> : ContentQuery<T>, IContentQuery<T, TR>
|
||||
where T : IContent
|
||||
@@ -242,6 +269,200 @@ namespace Orchard.ContentManagement {
|
||||
}
|
||||
}
|
||||
|
||||
public class DefaultExpressionFactory : IExpressionFactory {
|
||||
private readonly DefaultContentQuery _query;
|
||||
public ICriterion Criterion { get; private set; }
|
||||
public ICriteria Criteria { get; private set; }
|
||||
|
||||
public DefaultExpressionFactory(DefaultContentQuery query) {
|
||||
_query = query;
|
||||
}
|
||||
|
||||
public IExpressionFactory WithRecord(string path) {
|
||||
Criteria = _query.BindCriteriaByPath(_query.BindItemCriteria(), path);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IExpressionFactory WithVersionRecord(string path) {
|
||||
Criteria = _query.BindCriteriaByPath(_query.BindItemVersionCriteria(), path);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Eq(string propertyName, object value) {
|
||||
Criterion = Restrictions.Eq(propertyName, value);
|
||||
}
|
||||
|
||||
public void Like(string propertyName, object value) {
|
||||
Criterion = Restrictions.Like(propertyName, value);
|
||||
}
|
||||
|
||||
public void Like(string propertyName, string value, MatchMode matchMode, char? escapeChar) {
|
||||
Criterion = Restrictions.Like(propertyName, value);
|
||||
}
|
||||
|
||||
public void Like(string propertyName, string value, MatchMode matchMode) {
|
||||
Criterion = Restrictions.Like(propertyName, value);
|
||||
}
|
||||
|
||||
public void InsensitiveLike(string propertyName, string value, MatchMode matchMode) {
|
||||
Criterion = Restrictions.InsensitiveLike(propertyName, value);
|
||||
}
|
||||
|
||||
public void InsensitiveLike(string propertyName, object value) {
|
||||
Criterion = Restrictions.InsensitiveLike(propertyName, value);
|
||||
}
|
||||
|
||||
public void Gt(string propertyName, object value) {
|
||||
Criterion = Restrictions.Gt(propertyName, value);
|
||||
}
|
||||
|
||||
public void Lt(string propertyName, object value) {
|
||||
Criterion = Restrictions.Lt(propertyName, value);
|
||||
}
|
||||
|
||||
public void Le(string propertyName, object value) {
|
||||
Criterion = Restrictions.Le(propertyName, value);
|
||||
}
|
||||
|
||||
public void Ge(string propertyName, object value) {
|
||||
Criterion = Restrictions.Ge(propertyName, value);
|
||||
}
|
||||
|
||||
public void Between(string propertyName, object lo, object hi) {
|
||||
Criterion = Restrictions.Between(propertyName, lo, hi);
|
||||
}
|
||||
|
||||
public void In(string propertyName, object[] values) {
|
||||
Criterion = Restrictions.In(propertyName, values);
|
||||
}
|
||||
|
||||
public void In(string propertyName, ICollection values) {
|
||||
Criterion = Restrictions.In(propertyName, values);
|
||||
}
|
||||
|
||||
public void InG<T>(string propertyName, ICollection<T> values) {
|
||||
Criterion = Restrictions.InG(propertyName, values);
|
||||
}
|
||||
|
||||
public void IsNull(string propertyName) {
|
||||
Criterion = Restrictions.IsNull(propertyName);
|
||||
}
|
||||
|
||||
public void EqProperty(string propertyName, string otherPropertyName) {
|
||||
Criterion = Restrictions.EqProperty(propertyName, otherPropertyName);
|
||||
}
|
||||
|
||||
public void NotEqProperty(string propertyName, string otherPropertyName) {
|
||||
Criterion = Restrictions.NotEqProperty(propertyName, otherPropertyName);
|
||||
}
|
||||
|
||||
public void GtProperty(string propertyName, string otherPropertyName) {
|
||||
Criterion = Restrictions.GtProperty(propertyName, otherPropertyName);
|
||||
}
|
||||
|
||||
public void GeProperty(string propertyName, string otherPropertyName) {
|
||||
Criterion = Restrictions.GeProperty(propertyName, otherPropertyName);
|
||||
}
|
||||
|
||||
public void LtProperty(string propertyName, string otherPropertyName) {
|
||||
Criterion = Restrictions.LtProperty(propertyName, otherPropertyName);
|
||||
}
|
||||
|
||||
public void LeProperty(string propertyName, string otherPropertyName) {
|
||||
Criterion = Restrictions.LeProperty(propertyName, otherPropertyName);
|
||||
}
|
||||
|
||||
public void IsNotNull(string propertyName) {
|
||||
Criterion = Restrictions.IsNotNull(propertyName);
|
||||
}
|
||||
|
||||
public void IsNotEmpty(string propertyName) {
|
||||
Criterion = Restrictions.IsNotEmpty(propertyName);
|
||||
}
|
||||
|
||||
public void IsEmpty(string propertyName) {
|
||||
Criterion = Restrictions.IsEmpty(propertyName);
|
||||
}
|
||||
|
||||
public void And(Action<IExpressionFactory> lhs, Action<IExpressionFactory> rhs) {
|
||||
lhs(this);
|
||||
ICriterion a = Criterion;
|
||||
rhs(this);
|
||||
ICriterion b = Criterion;
|
||||
Criterion = Restrictions.And(a, b);
|
||||
}
|
||||
|
||||
public void Or(Action<IExpressionFactory> lhs, Action<IExpressionFactory> rhs) {
|
||||
lhs(this);
|
||||
ICriterion a = Criterion;
|
||||
rhs(this);
|
||||
ICriterion b = Criterion;
|
||||
Criterion = Restrictions.Or(a, b);
|
||||
}
|
||||
|
||||
public void Not(Action<IExpressionFactory> expression) {
|
||||
expression(this);
|
||||
ICriterion a = Criterion;
|
||||
Criterion = Restrictions.Not(a);
|
||||
}
|
||||
|
||||
public void Conjunction(Action<IExpressionFactory> expression, params Action<IExpressionFactory>[] otherExpressions) {
|
||||
var junction = Restrictions.Conjunction();
|
||||
foreach (var exp in Enumerable.Empty<Action<IExpressionFactory>>().Union(new[] { expression }).Union(otherExpressions)) {
|
||||
exp(this);
|
||||
junction.Add(Criterion);
|
||||
}
|
||||
|
||||
Criterion = junction;
|
||||
}
|
||||
|
||||
public void Disjunction(Action<IExpressionFactory> expression, params Action<IExpressionFactory>[] otherExpressions) {
|
||||
var junction = Restrictions.Disjunction();
|
||||
foreach (var exp in Enumerable.Empty<Action<IExpressionFactory>>().Union(new[] { expression }).Union(otherExpressions)) {
|
||||
exp(this);
|
||||
junction.Add(Criterion);
|
||||
}
|
||||
|
||||
Criterion = junction;
|
||||
}
|
||||
|
||||
public void AllEq(IDictionary propertyNameValues) {
|
||||
Criterion = Restrictions.AllEq(propertyNameValues);
|
||||
}
|
||||
|
||||
public void NaturalId() {
|
||||
Criterion = Restrictions.NaturalId();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class DefaultSortFactory : ISortFactory {
|
||||
private readonly DefaultContentQuery _query;
|
||||
public Order Order { get; private set; }
|
||||
public ICriteria Criteria { get; private set; }
|
||||
|
||||
public DefaultSortFactory(DefaultContentQuery query) {
|
||||
_query = query;
|
||||
}
|
||||
|
||||
public ISortFactory WithRecord(string path) {
|
||||
Criteria = _query.BindCriteriaByPath(_query.BindItemCriteria(), path);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ISortFactory WithVersionRecord(string path) {
|
||||
Criteria = _query.BindCriteriaByPath(_query.BindItemVersionCriteria(), path);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Asc(string propertyName) {
|
||||
Order = Order.Asc(propertyName);
|
||||
}
|
||||
|
||||
public void Desc(string propertyName) {
|
||||
Order = Order.Desc(propertyName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class CriteriaExtensions {
|
||||
|
||||
@@ -5,7 +5,7 @@ using Orchard.ContentManagement.Records;
|
||||
|
||||
namespace Orchard.ContentManagement {
|
||||
|
||||
public interface IContentQuery {
|
||||
public interface IContentQuery{
|
||||
IContentManager ContentManager { get; }
|
||||
IContentQuery<TPart> ForPart<TPart>() where TPart : IContent;
|
||||
}
|
||||
@@ -20,7 +20,10 @@ namespace Orchard.ContentManagement {
|
||||
|
||||
IContentQuery<TPart, TRecord> Join<TRecord>() where TRecord : ContentPartRecord;
|
||||
|
||||
IContentQuery<TPart> Where(Action<IExpressionFactory> predicate);
|
||||
IContentQuery<TPart, TRecord> Where<TRecord>(Expression<Func<TRecord, bool>> predicate) where TRecord : ContentPartRecord;
|
||||
|
||||
IContentQuery<TPart> OrderBy(Action<ISortFactory> order);
|
||||
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;
|
||||
}
|
||||
|
||||
49
src/Orchard/ContentManagement/IExpressionFactory.cs
Normal file
49
src/Orchard/ContentManagement/IExpressionFactory.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.ContentManagement {
|
||||
public interface IExpressionFactory {
|
||||
IExpressionFactory WithRecord(string recordName);
|
||||
IExpressionFactory WithVersionRecord(string recordName);
|
||||
|
||||
void Eq(string propertyName, object value);
|
||||
void Like(string propertyName, object value);
|
||||
void Like(string propertyName, string value, MatchMode matchMode, char? escapeChar);
|
||||
void Like(string propertyName, string value, MatchMode matchMode);
|
||||
void InsensitiveLike(string propertyName, string value, MatchMode matchMode);
|
||||
void InsensitiveLike(string propertyName, object value);
|
||||
void Gt(string propertyName, object value);
|
||||
void Lt(string propertyName, object value);
|
||||
void Le(string propertyName, object value);
|
||||
void Ge(string propertyName, object value);
|
||||
void Between(string propertyName, object lo, object hi);
|
||||
void In(string propertyName, object[] values);
|
||||
void In(string propertyName, ICollection values);
|
||||
void InG<T>(string propertyName, ICollection<T> values);
|
||||
void IsNull(string propertyName);
|
||||
void EqProperty(string propertyName, string otherPropertyName);
|
||||
void NotEqProperty(string propertyName, string otherPropertyName);
|
||||
void GtProperty(string propertyName, string otherPropertyName);
|
||||
void GeProperty(string propertyName, string otherPropertyName);
|
||||
void LtProperty(string propertyName, string otherPropertyName);
|
||||
void LeProperty(string propertyName, string otherPropertyName);
|
||||
void IsNotNull(string propertyName);
|
||||
void IsNotEmpty(string propertyName);
|
||||
void IsEmpty(string propertyName);
|
||||
void And(Action<IExpressionFactory> lhs, Action<IExpressionFactory> rhs);
|
||||
void Or(Action<IExpressionFactory> lhs, Action<IExpressionFactory> rhs);
|
||||
void Not(Action<IExpressionFactory> expression);
|
||||
void Conjunction(Action<IExpressionFactory> expression, params Action<IExpressionFactory>[] otherExpressions);
|
||||
void Disjunction(Action<IExpressionFactory> expression, params Action<IExpressionFactory>[] otherExpressions);
|
||||
void AllEq(IDictionary propertyNameValues);
|
||||
void NaturalId();
|
||||
}
|
||||
|
||||
public enum MatchMode {
|
||||
Exact,
|
||||
Start,
|
||||
End,
|
||||
Anywhere
|
||||
}
|
||||
}
|
||||
9
src/Orchard/ContentManagement/ISortFactory.cs
Normal file
9
src/Orchard/ContentManagement/ISortFactory.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Orchard.ContentManagement {
|
||||
public interface ISortFactory {
|
||||
ISortFactory WithRecord(string recordName);
|
||||
ISortFactory WithVersionRecord(string recordName);
|
||||
|
||||
void Asc(string propertyName);
|
||||
void Desc(string propertyName);
|
||||
}
|
||||
}
|
||||
@@ -169,6 +169,7 @@
|
||||
<Compile Include="ContentManagement\ContentIdentity.cs" />
|
||||
<Compile Include="ContentManagement\ContentItemBehavior.cs" />
|
||||
<Compile Include="ContentManagement\ContentPartBehavior.cs" />
|
||||
<Compile Include="ContentManagement\ISortFactory.cs" />
|
||||
<Compile Include="ContentManagement\DefaultContentDisplay.cs" />
|
||||
<Compile Include="ContentManagement\Drivers\ContentShapeResult.cs" />
|
||||
<Compile Include="ContentManagement\FieldStorage\IFieldStorageEvents.cs" />
|
||||
@@ -178,6 +179,7 @@
|
||||
<Compile Include="ContentManagement\Handlers\ImportContentContext.cs" />
|
||||
<Compile Include="ContentManagement\Handlers\TitleAspectHandler.cs" />
|
||||
<Compile Include="ContentManagement\IContentBehavior.cs" />
|
||||
<Compile Include="ContentManagement\IExpressionFactory.cs" />
|
||||
<Compile Include="ContentManagement\ImportContentSession.cs" />
|
||||
<Compile Include="ContentManagement\MetaData\Services\ISettingsFormatter.cs" />
|
||||
<Compile Include="ContentManagement\QueryHints.cs" />
|
||||
|
||||
Reference in New Issue
Block a user