首页
/ System.Linq.Dynamic.Core 实现不区分大小写排序的技术方案

System.Linq.Dynamic.Core 实现不区分大小写排序的技术方案

2025-07-10 17:02:57作者:郁楠烈Hubert

在数据库查询中,SQL 语句默认执行不区分大小写的排序操作,但在使用 System.Linq.Dynamic.Core 进行动态 LINQ 查询时,默认的排序行为是区分大小写的。本文将详细介绍如何在 System.Linq.Dynamic.Core 中实现与 SQL 一致的不区分大小写排序功能。

问题背景

当开发者从 SQL 查询迁移到 LINQ 查询时,经常会遇到排序行为不一致的问题。例如,在 SQL 中使用 ORDER BY [EInfo].[Co], [EInfo].[FirstName], [EInfo].[LastName] 会执行不区分大小写的排序,而直接使用 System.Linq.Dynamic.Core 的 OrderBy 方法则会区分大小写。

解决方案探索

1. 直接使用 StringComparer

对于简单场景,可以直接在 OrderBy 方法中传入 StringComparer.OrdinalIgnoreCase

var sortedRows = queryableRows.OrderBy("FirstName", StringComparer.OrdinalIgnoreCase);

2. 处理复杂数据类型

当处理 DataTable 等复杂数据类型时,上述方法可能不适用,因为 DataColumn 的类型是 object。这时需要自定义比较器:

public class DataColumnOrdinalIgnoreCaseComparer : IComparer
{
    public int Compare(object? x, object? y)
    {
        if (x == null && y == null) return 0;
        if (x == null) return -1;
        if (y == null) return 1;
        
        if (x is string xAsString && y is string yAsString)
        {
            return StringComparer.OrdinalIgnoreCase.Compare(xAsString, yAsString);
        }
        
        return Comparer.Default.Compare(x, y);
    }
}

3. 多字段排序实现

对于多字段排序场景,可以链式调用 ThenBy 方法:

var sortedRows = queryableRows
    .OrderBy("Co ID_0")
    .ThenBy("First Name_2", StringComparer.OrdinalIgnoreCase)
    .ThenBy("Last Name_3", StringComparer.OrdinalIgnoreCase);

技术要点

  1. 比较器选择StringComparer.OrdinalIgnoreCase 提供不区分大小写的字符串比较
  2. 空值处理:自定义比较器需要正确处理 null 值情况
  3. 类型安全:比较前应检查对象是否为字符串类型
  4. 性能考虑:避免在排序过程中频繁进行类型转换

实际应用示例

以下是一个完整的 DataTable 排序示例:

var persons = new DataTable();
persons.Columns.Add("FirstName", typeof(string));
persons.Columns.Add("Nickname", typeof(string));
persons.Columns.Add("Income", typeof(decimal)).AllowDBNull = true;

// 添加示例数据
persons.Rows.Add("alex", DBNull.Value, 5000.50m);
persons.Rows.Add("MAGNUS", "Mag", 5000.50m);
persons.Rows.Add("Terry", "Ter", 4000.20m);
persons.Rows.Add("Charlotte", "Charl", DBNull.Value);

var queryableRows = persons.AsEnumerable().AsQueryable();
var comparer = new DataColumnOrdinalIgnoreCaseComparer();

// 执行不区分大小写的排序
var sortedRows = queryableRows.OrderBy("FirstName", comparer).ToList();

总结

通过自定义比较器,我们可以在 System.Linq.Dynamic.Core 中实现与 SQL 一致的不区分大小写排序行为。这种方法不仅适用于简单字符串排序,也能处理复杂数据类型和多字段排序场景,为开发者提供了灵活而强大的排序功能。

登录后查看全文
热门项目推荐
相关项目推荐