1
我有一個名爲Property的內容類型,它是在Orchard管理Web界面中創建的。物業包含多個字段,其中2個是地址和價格。Orchard Query基於URL參數的內容類型查詢排序提供程序
我已經創建了一個Query過濾屬性內容類型,並希望通過Projection根據URL查詢字符串參數進行排序。例如。 〜/ PropertyProjection?sortfield = price & sortasc = true將按價格升序對屬性進行排序。
下面的代碼正在分揀價格,但我想知道是否有更好,更簡單,更高效的方式來實現這一點。特別是我想要自動設置propertyName和dataType變量。
using System;
using System.Collections.Generic;
using System.Linq;
using Orchard;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.MetaData;
using Orchard.Localization;
using Orchard.Projections.Descriptors.SortCriterion;
using Orchard.Projections.FieldTypeEditors;
using Orchard.Projections.Services;
using Orchard.Utility.Extensions;
namespace CustomModule.Providers {
public class PropertySortCriterionProvider : ISortCriterionProvider {
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly IEnumerable<IContentFieldDriver> _contentFieldDrivers;
private readonly IEnumerable<IFieldTypeEditor> _fieldTypeEditors;
private readonly IWorkContextAccessor _workContextAccessor;
public PropertySortCriterionProvider(
IContentDefinitionManager contentDefinitionManager,
IEnumerable<IContentFieldDriver> contentFieldDrivers,
IEnumerable<IFieldTypeEditor> fieldTypeEditors,
IWorkContextAccessor workContextAccessor)
{
_contentDefinitionManager = contentDefinitionManager;
_contentFieldDrivers = contentFieldDrivers;
_fieldTypeEditors = fieldTypeEditors;
_workContextAccessor = workContextAccessor;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
public void Describe(DescribeSortCriterionContext describe) {
var descriptor = describe.For("Custom Property", T("Custom Property"), T("Custom Property sorts"));
descriptor.Element("PropertySortQueryParam", T("PropertySortQueryParam"),
T("Sort Property by the HTTP Query Sort parameters"),
context => ApplyFilter(context),
context => DisplaySortCriterion(context)
);
}
public void ApplyFilter(SortCriterionContext context)
{
//bool ascending = Convert.ToBoolean(context.State.Sort);
var sortField = _workContextAccessor.GetContext().HttpContext.Request.Params["sortfield"];
var ascending = true;
if (!bool.TryParse(_workContextAccessor.GetContext().HttpContext.Request.Params["sortasc"], out ascending))
ascending = true;
if (!string.IsNullOrEmpty(sortField)) {
var propertyName = "";
Type dataType = null;
var fieldName = "";
if (sortField.ToLower() == "price") {
propertyName = "Property.Price.";
dataType = typeof (Decimal);
fieldName = "Price";
}
//if we have valid sort criteria from the URL param
if (dataType != null) {
IFieldTypeEditor fieldTypeEditor = _fieldTypeEditors.FirstOrDefault(x => x.CanHandle(dataType));
var part = _contentDefinitionManager.ListPartDefinitions().First(p => p.Name == "Property");
var field = part.Fields.Where(f => f.Name == fieldName);
// use an alias with the join so that two filters on the same Field Type wont collide
var relationship = fieldTypeEditor.GetFilterRelationship(propertyName.ToSafeName());
// generate the predicate based on the editor which has been used
Action<IHqlExpressionFactory> predicate = y => y.Eq("PropertyName", propertyName);
// combines the predicate with a filter on the specific property name of the storage, as implemented in FieldIndexService
// apply where clause
context.Query = context.Query.Where(relationship, predicate);
// apply sort
context.Query = ascending
? context.Query.OrderBy(relationship, x => x.Asc("Value"))
: context.Query.OrderBy(relationship, x => x.Desc("Value"));
}
}
}
public LocalizedString DisplaySortCriterion(SortCriterionContext context) {
bool ascending = Convert.ToBoolean(context.State.Sort);
if (ascending) {
return T("Ordered by Custom Property HTTP Query Sort parameters ascending");
}
return T("Ordered by Custom property HTTP Query Sort parameters descending");
}
}
}
上面的代碼是基於關閉ContentFieldsSortCriterion在Orchard.Projections.Providers.SortCriteria
請提供你的答案的代碼示例。
乾杯,
安德魯
我有一個預感,這可以完全通過預測沒有任何代碼。你試過這個嗎?您可以在投影過濾器中使用查詢字符串標記。 –
是的,我試過沒有運氣。如果我在一個方向上對單個領域進行排序,那麼不用擔心。但我不知道基於查詢字符串參數選擇字段的方法,然後在基於另一個查詢字符串參數的方向上對該字段進行排序。 – Andrew
啊,我明白你的意思了。 –