按特定集合列表排序的 LINQ 查询

LINQ query for ordering by a specific set list

我正在开发一个小的音乐应用程序,我要在其中填充一个下拉列表。

我的问题出在我 运行 此处的 LINQ 查询中:

var results = (from x in db.Keys
               where x.SongId == songId
               orderby x.ChordKey ascending
               select x.ChordKey).ToList();

我的 ChordKey 值总是只会是:

Ab, A, Bb, B, C, C#, Db, D, Eb, E, F, F#, Gb, G

我希望它们按照上面的顺序排列,不幸的是,如果按字母顺序排列,A 将出现在 Ab 之前。有没有办法按照上面的具体标准来排序?

对具有按您希望的方式排序的基础整数值的键使用枚举。

public enum ChordKey 
{Ab=1, A=2, Bb=3, B=4, C=5, 
 Db=6, D=7, Eb=8, E=9, 
 F=10, Gb=11, G=12}

然后

var results = (from x in db.Keys
           where x.SongId == songId
           orderby (int)x.ChordKey ascending
           select x.ChordKey).ToList();

您可以有一个自定义排序列表,您可以使用它的项目顺序来订购您的特定列表。这可以通过创建自定义订单列表并使用该列表中每个项目的索引来完成。如果有 ChordKey 个值可能不在您的列表中(似乎不是这种情况,那么您需要进一步检查):

var sortingOrder = new List<string>()
{
    "Ab", "A", "Bb", "B", "C", "C#", "Db", "D", "Eb", "E", "F", "F#", "Gb", "G"
};

results = results.OrderBy(x => sortingOrder.IndexOf(x)).ToList();

这会根据排序列表中项目的索引对列表中的每个项目进行排序。

另一个解决方案是创建 class ChordKey 并实现 IComparer 接口:

class ChordKey : IComparer {
    // the number of the Chord. For Ab is 1 (or 0), for "G" is 14 (or 13) for example
    public int Id { get; set; } 
    // name of the Chord. For Ab is "Ab"
    public string Name { get; set; }

    public ChordKey(string name, int id) {
        Name = name;
        Id = id;
    }

    public int Compare(object a, object b) {
        var c1 = (ChordKey)a;
        var c2 = (ChordKey)a;

        return c1.Id - c2.Id;
    }
}

现在您可以在 LINQ 查询中使用它了:

var results = (from x in db.Keys
               where x.SongId == songId
               orderby x.ChordKey.Id ascending
               select x.ChordKey).ToList();