簡體   English   中英

如何使用 linq 中的自定義列值對列表進行排序?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM