Linq Select OrderBy ThenBy Kendo 下拉列表

Linq Select OrderBy ThenBy Kendo Dropdownlist

我的应用程序是 MVC5。我正在填充国家/地区 Kendo 下拉列表,尝试使用以下方法将加拿大和美国置于列表顶部:

     public JsonResult GetCountries()
            {
                return Json(db.Country.OrderBy(x => x.TwoCharCountryCode == "CA")
                .ThenBy(x => x.TwoCharCountryCode == "US").ThenBy(x => x.CountryName)
             .Select(c => new { CountryId = c.CountryId, CountryName = c.CountryName }), JsonRequestBehavior.AllowGet);
            }



              @(Html.Kendo().DropDownList()
                  .Name("Country")
                  .HtmlAttributes(new { style = "width:300px;", id="Country", value = ViewBag.CountryId })
                 .OptionLabel("Select country...")
                  .DataTextField("CountryName")
                  .DataValueField("CountryId")
                  .DataSource(source =>
                  {
                      source.Read(read =>
                      {
                          read.Action("GetCountries", "Home");
                      }).ServerFiltering(true);
                  })
                  .Events(e => {e.Select("onSelect");
                  }))

我把加拿大和美国放在最后!

我可以使用两个 ThenBy 吗?或者我做错了什么?

当您执行 .OrderByThenBy 布尔值时,False,即 0,将始终出现在 True 之前,即 1。

如果您必须将加拿大和美国放在列表的首位,然后对其余的进行排序,我会先将这两个从列表中删除,然后重新排列列表的其余部分,然后将所有内容重新组合在一起:

public JsonResult GetCountries()
{
    var canadaOrUsa = db.Country
        .Where(x => x.TwoCharCountryCode == "CA" ||
                    x.TwoCharCountryCode == "US")
        .OrderBy(x => x.CountryName);

    var theRest = db.Country
        .Where(x => x.TwoCharCountryCode != "CA" &&
                    x.TwoCharCountryCode != "US")
        .OrderBy(x => x.CountryName);

    return Json(
        canadaOrUsa.Concat(theRest)
            .Select(x => new {
                CountryId = x.CountryId, 
                CountryName = x.CountryName
            }, JsonRequestBehavior.AllowGet);
}

如果你不想枚举列表两次,我猜你可以.ToList()从你的db.Country中找到加拿大和美国,并从列表中取出它们,向左排序-结束,然后将它们放回列表的开头。

@configurator 在这里写了一个关于将项目移动到列表顶部的扩展方法:

public static IEnumerable<T> MoveToTop(IEnumerable<T> list, Func<T, bool> func) {
    return list.Where(func)
               .Concat(list.Where(item => !func(item)));
}

您可以使用它来减少需要编写的代码行:

public JsonResult GetCountries()
{
    var result = db.Country
        .OrderBy(x => x.CountryName)
        .MoveToTop(x => x.TwoCharCountryCode == "CA" ||
                    x.TwoCharCountryCode == "US");

    return Json(
        result
            .Select(x => new {
                CountryId = x.CountryId, 
                CountryName = x.CountryName
            }, JsonRequestBehavior.AllowGet);
}

只需强制 LINQ 翻译器创建正确的查询:

var query = db.Country
   .OrderBy(x => x.TwoCharCountryCode == "CA" 
      ? 0 
      : x.TwoCharCountryCode == "US"
      ? 1 : 2)
   .ThenBy(x => x.CountryName)
   .Select(c => new { CountryId = c.CountryId, CountryName = c.CountryName });