C#Linq OrderBy过滤null或空值为last

Cih*_*gun 28 c# linq expression

我尝试使用自定义orderby扩展方法,我成功地处理了我的代码,但另外我想在结果中列出null或空值或零值,任何人都可以帮我解决这个问题?

这是我对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);
    }
Run Code Online (Sandbox Code Playgroud)

提前致谢

Raj*_*jes 41

最简单的方法是使用

OrderBy(e => String.IsNullOrEmpty(e.TeamName)
Run Code Online (Sandbox Code Playgroud)

这不需要任何扩展方法或自定义IComparer实现等.

var entries = repository.Race.Where(e => e.EventId == id)
                      .OrderBy(e => String.IsNullOrEmpty(e.TeamName))
                      .ThenBy(e => e.LastName)
                      .ThenBy(e => e.FirstName);
Run Code Online (Sandbox Code Playgroud)

  • 但为此你必须添加`.ThenBy(e => e.TeamName)`.`.OrderBy(e => String.IsNullOrEmpty(e.TeamName))`只会按布尔结果排序,而不能按内容本身排序. (3认同)

Dav*_*son 24

不使用扩展方法....

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);
            }
        }
 }
Run Code Online (Sandbox Code Playgroud)

EmptyStringsAreLast比较器传递给OrderByLambda表达式.在此解决方案中,参加比赛的团队应按字母顺序排列,但非关联的比赛条目应在结束时出现.

var entries = repository.Race.Where(e => e.EventId == id)
                          .OrderBy(e => e.TeamName, new EmptyStringsAreLast())
                          .ThenBy(e => e.LastName)
                          .ThenBy(e => e.FirstName);
Run Code Online (Sandbox Code Playgroud)