グリッドの並べ替えコードの記述をより簡単に操作および保守できるようにし、コードの繰り返しを抑えることができるように、クイッククラスを作成しようとしています。これを行うために、私は次のクラスを思いついた:
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; }
}
}
アイデアは、さまざまなソートオプション、そのために使用されるOrderBy式、およびオプションでそのソートオプションに関連するオブジェクトのクイック構成を作成することです。これにより、私のコードは次のようになります。
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);
}
やるだけでソートできます
// Get desired sorting configuration
InitSortConfig();
var sortOption = _sortConfig.GetSortOption(sort);
bool isDescendingSort = sort.EndsWith("desc", StringComparison.OrdinalIgnoreCase);
// Setup columns
InitSortLinks();
if (sortOption.RelatedObject != null)
{
// Make modifications to html anchor
}
// Form query
var query = PodDataContext.xosPodOptimizedSearches.AsQueryable();
if (isDescendingSort)
query = query.OrderByDescending(sortOption.SortExpression);
else
query = query.OrderBy(sortOption.SortExpression);
これは、並べ替えられた変数が文字列の場合はうまく機能しますが、文字列でない場合は、次の例外が発生します。Cannot order by type 'System.Object'.
これは、式をとして保存しているためでExpression<Func<TSource, object>>
あり、その2番目のジェネリックについてより具体的ではないためだと思います。さまざまな並べ替えオプション(文字列以外のプロパティの場合でも)をすべて1つのクラスに保持する方法がわかりません。
問題の1つは、Linq.OrderBy()
句がパラメータとして使用されることだと思いますが、どのように推論できるExpression<Func<TSource, TKey>>
かについて頭を悩ませていません。したがって、その推論を利用してこれらの式を保存する方法を理解できません。適切な。Linq.OrderBy()
TKey
TKey
何か案は?