I am trying to create a quick class so that I can make the record sorting code for the grid much easier to operate and maintain, and also keep the code repeating. For this, I came up with the following class:
public class SortConfig<TSource, TRelatedObject> where TSource : class where TRelatedObject : class
{
public IList<SortOption> Options { get; protected set; }
public SortOption DefaultOption { get; set; }
public SortConfig()
{
Options = new List<SortOption>();
}
public void Add(string name, Expression<Func<TSource, object>> sortExpression, TRelatedObject relatedObject, bool isDefault = false)
{
var option = new SortOption
{
FriendlyName = name,
SortExpression = sortExpression,
RelatedObject = relatedObject
};
Options.Add(option);
if (isDefault)
DefaultOption = option;
}
public SortOption GetSortOption(string sortName)
{
if (sortName.EndsWith("asc", StringComparison.OrdinalIgnoreCase))
sortName = sortName.Substring(0, sortName.LastIndexOf("asc", StringComparison.OrdinalIgnoreCase));
else if (sortName.EndsWith("desc", StringComparison.OrdinalIgnoreCase))
sortName = sortName.Substring(0, sortName.LastIndexOf("desc", StringComparison.OrdinalIgnoreCase));
sortName = sortName.Trim();
var option = Options.Where(x => x.FriendlyName.Trim().Equals(sortName, StringComparison.OrdinalIgnoreCase))
.FirstOrDefault();
if (option == null)
{
if (DefaultOption == null)
throw new InvalidOperationException(
string.Format("No configuration found for sort type of '{0}', and no default sort configuration exists", sortName));
option = DefaultOption;
}
return option;
}
public class SortOption
{
public string FriendlyName { get; set; }
public Expression<Func<TSource, object>> SortExpression { get; set; }
public TRelatedObject RelatedObject { get; set; }
}
}
The idea is that you create a quick configuration of various sorting parameters, which uses the expression OrderBy and, possibly, the object associated with this sorting parameter. This allows me to look like this:
protected void InitSortConfig()
{
_sortConfig = new SortConfig<xosPodOptimizedSearch, HtmlAnchor>();
_sortConfig.Add("name", (x => x.LastName), lnkSortName, true);
_sortConfig.Add("team", (x => x.SchoolName), lnkSortTeam);
_sortConfig.Add("rate", (x => x.XosRating), lnkSortRate);
_sortConfig.Add("pos", (x => x.ProjectedPositions), null);
_sortConfig.Add("height", (x => x.Height), lnkSortHeight);
_sortConfig.Add("weight", (x => x.Weight), lnkSortWeight);
_sortConfig.Add("city", (x => x.SchoolCity), lnkSortCity);
_sortConfig.Add("state", (x => x.SchoolState), lnkSortState);
}
and then I can sort by just doing
InitSortConfig();
var sortOption = _sortConfig.GetSortOption(sort);
bool isDescendingSort = sort.EndsWith("desc", StringComparison.OrdinalIgnoreCase);
InitSortLinks();
if (sortOption.RelatedObject != null)
{
}
var query = PodDataContext.xosPodOptimizedSearches.AsQueryable();
if (isDescendingSort)
query = query.OrderByDescending(sortOption.SortExpression);
else
query = query.OrderBy(sortOption.SortExpression);
This works fine when the sorted variable is a string, but when it is not a string, I get the following exception: Cannot order by type 'System.Object'.
, , Expression<Func<TSource, object>> 2- . , ( , ) .
, , Linq.OrderBy() Expression<Func<TSource, TKey>> , , Linq.OrderBy() , TKey , , TKey.
?