我正在尝试构建一个对可空字段进行排序的ASP.NET页面。我想要做的是,如果可排序字段中有空值,则始终将这些行抛出到列表的末尾。否则,它们出现在列表的开头,我可以想象在你到达A-Z排序元素之前的空值行的页面和页面。
我在ASP.NET框架中工作。可排序列的解决方案是针对此处的GridViewDataSource构建动态查询:
public static class QueryExtensions {
public static IQueryable<T> SortBy<T>(this IQueryable<T> source, string propertyName) {
if (source == null) {
throw new ArgumentNullException("source");
}
// DataSource control passes the sort parameter with a direction
// if the direction is descending
int descIndex = propertyName.IndexOf(" DESC");
if (descIndex >= 0) {
propertyName = propertyName.Substring(0, descIndex).Trim();
}
if (String.IsNullOrEmpty(propertyName)) {
return source;
}
ParameterExpression parameter = Expression.Parameter(source.ElementType, String.Empty);
MemberExpression property = Expression.Property(parameter, propertyName);
LambdaExpression lambda = Expression.Lambda(property, parameter);
string methodName = (descIndex < 0) ? "OrderBy" : "OrderByDescending";
Expression methodCallExpression = Expression.Call(typeof(Queryable), methodName,
new Type[] { source.ElementType, property.Type },
source.Expression, Expression.Quote(lambda));
return source.Provider.CreateQuery<T>(methodCallExpression);
}
}
因为我在这个框架内工作,所以我不会改变这个函数的工作方式。相反,我试图用这个签名重载方法:
public static IQueryable<T> SortBy<T>(this IQueryable<T> source, string propertyName, bool nullsToEnd)
我遇到的问题是我无法弄清楚如何编辑&#39; methodName&#39;特别允许这种类型的排序(A-Z在末尾带有空值)。
关于什么可以做到这一点的任何想法?
由于
答案 0 :(得分:2)
我不认为有一个方法名称本身会做你想要的。相反,您需要在此方案中选择不同的方法重载,一个采用自定义IComparer实例的方法重载。然后,您需要实现一个包装Comparer.Default的IComparer,在不涉及null时返回该comparer的结果,并在它们出现时将nulls排序到末尾。
请注意,如果您希望OrderBy和OrderByDescending案例的末尾都有空值,则需要相应地调整IComparer实现。要么它处理空值和升序/降序选项,要么在执行“降序”的情况下将空值排序到开头(个人,因为你必须根据升序/降序状态调整IComparer,我会继续,只让IComparer处理上升/下降部分。
例如:
class NullsAtEndComparer<T> : IComparer<T> where T : class
{
private static readonly IComparer<T> _baseComparer = Comparer<T>.Default;
private readonly bool _ascending;
public NullsAtEndComparer(bool ascending = true)
{
_ascending = ascending;
}
public int Compare(T t1, T t2)
{
if (object.ReferenceEquals(t1, t2))
{
return 0;
}
if (t1 == null)
{
return 1;
}
if (t2 == null)
{
return -1;
}
return _ascending ? _baseComparer.Compare(t1, t2) : _baseComparer.Compare(t2, t1);
}
}
然后对于“结束时的空值”场景,只需始终使用OrderBy方法并为该方法提供上述IComparer实现的实例。