我尝试使用自定义orderby扩展方法,我成功地处理了我的代码,但另外我想在结果中列出空值或空值或零值,任何人都可以帮我解决这个问题吗?
这是orderby的扩展方法
public static IQueryable<T> OrderBy<T>(this IQueryable<T> q, string SortField, bool isAsc)
{
//var nullExpr = Expression.Constant(null, typeof(T));
var param = Expression.Parameter(typeof(T), "p");
var prop = Expression.Property(param, SortField);
var exp = Expression.Lambda(prop, param);
string method = isAsc ? "OrderBy" : "OrderByDescending";
Type[] types = new Type[] { q.ElementType, exp.Body.Type };
var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
return q.Provider.CreateQuery<T>(mce);
}
提前致谢
答案 0 :(得分:35)
最简单的方法是使用
OrderBy(e => String.IsNullOrEmpty(e.TeamName)
这不需要任何扩展方法或自定义IComparer
实现等。
var entries = repository.Race.Where(e => e.EventId == id)
.OrderBy(e => String.IsNullOrEmpty(e.TeamName))
.ThenBy(e => e.LastName)
.ThenBy(e => e.FirstName);
答案 1 :(得分:21)
不使用扩展方法......
创建自定义IComparer<string>
以在使用默认String.Compare
之前检查空值。如果使用标准字符串比较,则第一次检查将返回-1而不是1或1而不是-1。
/// <summary>
/// Returns -1 instead of 1 if y is IsNullOrEmpty when x is Not.
/// </summary>
public class EmptyStringsAreLast : IComparer<string>
{
public int Compare(string x, string y)
{
if (String.IsNullOrEmpty(y) && !String.IsNullOrEmpty(x))
{
return -1;
}
else if (!String.IsNullOrEmpty(y) && String.IsNullOrEmpty(x))
{
return 1;
}
else
{
return String.Compare(x, y);
}
}
}
将您的EmptyStringsAreLast
比较器传递到Lambda表达式的OrderBy
。在此解决方案中,参加比赛的团队应按字母顺序排列,但非关联的参赛作品应在最后出现。
var entries = repository.Race.Where(e => e.EventId == id)
.OrderBy(e => e.TeamName, new EmptyStringsAreLast())
.ThenBy(e => e.LastName)
.ThenBy(e => e.FirstName);
答案 2 :(得分:2)
这个答案可能就是你最初想要的 - 使用你的通用扩展方法:
Release
答案 3 :(得分:0)
在Dave Anson's回答的基础上,您可以使用Comparer.Create()从lambda创建Comparer。以下是unsorted
字符串字段排序myString
的示例,其中null
或空字符串最后出现。
var sorted = unsorted.OrderBy(x => x.myString, Comparer<string>.Create((x, y) => {
if ( string.IsNullOrEmpty(y) && !string.IsNullOrEmpty(x)) return -1;
else if (!string.IsNullOrEmpty(y) && string.IsNullOrEmpty(x)) return +1;
else return string.Compare(x, y);
}))
(首先将它们放在1
常数上)
答案 4 :(得分:0)
它对我有用:
private static IQueryable<T> GetOrderQuery<T>(this IQueryable<T> q, BaseFilterCollection filter)
{
q = q.OrderBy(GetExpression<T>(filter.SortField));
var param = Expression.Parameter(typeof(T), "p");
var prop = Expression.Property(param, filter.SortField);
var exp = Expression.Lambda(prop, param);
string method = filter.SortDirection == SortDirectionType.Asc ? "ThenBy" : "ThenByDescending";
Type[] types = { q.ElementType, exp.Body.Type };
var rs = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
return q.Provider.CreateQuery<T>(rs);
}
private static Expression<Func<T, bool>> GetExpression<T>(string sortField)
{
ParameterExpression param = Expression.Parameter(typeof(T), "p");
Expression prop = Expression.Property(param, sortField);
var info = typeof(T).GetProperty(sortField, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
Expression exp = Expression.Equal(prop, info.PropertyType.IsValueType
? Expression.Constant(Activator.CreateInstance(info.PropertyType))
: Expression.Constant(null));
return Expression.Lambda<Func<T, bool>>(exp, param);
}
答案 5 :(得分:0)
你不需要复杂化,最简单的方法是做这样的事情:
YourList.OrderByDescending(x => string.IsNullOrEmpty(x.value)
使用 OrderByDescending 或 OrderBy,具体取决于您想在开头还是最后看到空字符串。
问候