[英]How to sort List using custom column values in linq?
網核、Ef核和linq。 我有列狀態表。 它保存值 New、In-Progress 和 Closed。 當我將使用 New 查詢所有行時,應該首先出現,然后是進行中並關閉。 下面是我的代碼。
var Requests = await this.RequestRepository.GetAsync(x => x.IsActive == true && x.CreatedBy == LoggedInUser, null, x => x.Country).ConfigureAwait(false);
下面是我的 GetAsync 方法
public async Task<IEnumerable<T>> GetAsync(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, params Expression<Func<T, object>>[] includes)
{
IQueryable<T> query = this.dbSet;
foreach (Expression<Func<T, object>> include in includes)
{
query = query.Include(include);
}
if (filter != null)
{
query = query.Where(filter);
}
if (orderBy != null)
{
query = orderBy(query);
}
return await query.ToListAsync().ConfigureAwait(false);
}
所以我希望所有狀態為 New 的行應該首先出現,然后是 In-Progress 並關閉。 無論如何,我都找不到解決辦法。 誰能幫我寫這個。 任何幫助,將不勝感激。 謝謝
如果您放棄這種“幫助”方法並直接使用 LINQ,您的生活可能會容易得多。 看看它的可讀性有多明顯:
var apps = db.FundingApplications
.Include(x => x.Applicant)
.Where(x => x.ApplicationDate.Year == DateTime.Now.Year)
.OrderBy(x => (int)x.Status)
(為了簡潔,我跳過了等待/異步,不是因為我提倡同步)
狀態當然是一個枚舉,例如:
enum Status{
New, Inprogress, Closed
}
如果您的枚舉笨拙地不是這樣的數字順序,而是例如
enum Status {
New = 20,
InProgress = 1,
Closed = 99
}
然后,您可以在 ToString 之后通過降序對其進行排序(您會注意到名稱按字母倒序排列)或使用映射的字典創建映射,例如d[New] = 0, d[InProgress] = 1...
,或者如果在 OrderBy 中設置,則執行(內聯)。
OrderByDescending(x => x.Status.ToString("g"));
var d = new Dictionary<status, int>() {
{New, 0}, {InProg,1}, {Closed,2}
};
OrderBy(x => d[x.Status]);
OrderBy(x => x.Status == Status.New ? 0 : (x.Status == Status.InProg ? 1 : 2))
但是,只有最后一個有真正的機會在服務器上執行,並且只有在您不重命名它們或添加破壞排序的新名稱時,按其名稱排序才會起作用。
我也很欣賞其他答案中給出的 OrderBy/ThenBy 並認為它很好,但我認為應該注意測試它是在服務器還是客戶端上執行,因為它執行 boolean 比較並且很多數據庫沒有使用布爾值作為數據類型,或者如果他們這樣做,它們可能會在 truey (1) 之前排序 falsy (0)
OrderBy(x => x.Status == New)
可能就在那時,它將所有已關閉和 InProg 排序在 New 之前,因為如果由服務器評估 boolean 的結果是 0 表示 InProg/已關閉,1 表示新。 MySql 和 Postgres 將是我的首選,因為他們擔心這將被服務器評估,因為它們確實允許 boolean 類型值在其他 dbs 不允許的上下文中。
因此,請注意a)這種排序正在評估您期望和想要的位置(客戶端/服務器)和b)如果它真的在服務器上評估服務器按您的意願訂購它
編輯,剛剛看到您的評論表明 Status 不是枚舉而是一組字符串常量?
如果您的數據庫值實際上是字符串並且狀態從來都不是枚舉,那么您可以通過降序對它們進行排序
OrderByDescending(x => x.Status)
我已根據您的要求制作了示例代碼。 它在我的工作正常。 請參考這里。 希望這也適用於您的代碼。
using System;
using System.Collections.Generic;
using System.Linq;
namespace Test
{
public class Program
{
public static void Main(string[] args)
{
List<Name> list = new List<Name>
{
new Name { FirstName = "Nishan1", LastName = "Dhungana1", Status = Status.Closed},
new Name { FirstName = "Nishan2", LastName = "Dhungana2", Status = Status.New},
new Name { FirstName = "Nishan3", LastName = "Dhungana3", Status = Status.New},
new Name { FirstName = "Nishan4", LastName = "Dhungana4", Status = Status.Closed},
new Name { FirstName = "Nishan5", LastName = "Dhungana5", Status = Status.Closed},
new Name { FirstName = "Nishan6", LastName = "Dhungana6", Status = Status.InProgress},
new Name { FirstName = "Nishan7", LastName = "Dhungana7", Status = Status.Closed},
new Name { FirstName = "Nishan8", LastName = "Dhungana8", Status = Status.InProgress},
new Name { FirstName = "Nishan9", LastName = "Dhungana9", Status = Status.InProgress},
new Name { FirstName = "Nishan10", LastName = "Dhungana10", Status = Status.New},
new Name { FirstName = "Nishan11", LastName = "Dhungana11", Status = Status.New}
};
list = list.OrderByDescending(x => x.Status == Status.New)
.ThenByDescending(x => x.Status == Status.InProgress)
.ThenByDescending(x => x.Status == Status.Closed)
.ToList();
Console.WriteLine("hey");
Console.ReadLine();
}
}
public class Name
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Status Status { get; set; }
}
public enum Status
{
New = 1,
InProgress = 2,
Closed = 3
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.