c# - 不区分大小写的排序不起作用(.NET Core、EF)
问题描述
我想以不区分大小写的方式对从 Postgresql 数据库中检索的项目列表进行排序。
假设我有以下未排序的值:A, B, a, c, b, C
我想:A, a, B, b, C, c
但现在我得到:A, B, C, a, b, c
我在这里用错了 StringComparison.OrdinalIgnoreCase 吗?
感谢您的任何帮助或提示!
public class SortingInfo
{
public string SortColumn { get; set; }
public SortOrder SortOrder { get; set; }
}
public Task<List<MyCustomType>> GetItemsAsync(SortingInfo sortingInfo)
{
var items = _itemsRepo
.Query
.ApplySort(sortingInfo)
.ToList();
var mappedData = _mapper.Map<List<Entities.MyCustomType>, List<MyCustomType>>(items);
return Task.FromResult(mappedData);
}
public static IQueryable<T> ApplySort<T>(this IQueryable<T> query, SortingInfo sortingInfo)
{
var propertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
var objectProperty = propertyInfos.FirstOrDefault(p =>
p.Name.Equals(sortingInfo.SortColumn.Trim(), StringComparison.OrdinalIgnoreCase));
if (objectProperty == null)
{
return query;
}
var sortingOrder = sortingInfo.SortOrder == SortOrder.Asc
? "ascending"
: "descending";
return query.OrderBy($"{objectProperty.Name} {sortingOrder}");
}
解决方案
我怀疑以这种方式订购您的物品的原因是由于您当前的整理。
您可以强制不区分大小写,也可以强制查询运行并在代码中排序:
public static IEnumerable<T> ApplySort<T>(this IQueryable<T> query, SortingInfo sortingInfo)
{
var propertyInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
var objectProperty = propertyInfos.FirstOrDefault(p =>
p.Name.Equals(sortingInfo.SortColumn.Trim(), StringComparison.OrdinalIgnoreCase));
if (objectProperty == null)
{
return query;
}
var param = Expression.Parameter(typeof(T));
LambdaExpression lambda = Expression.Lambda(Expression.Property(param, sortingInfo.SortColumn), param);
var materialisedQuery = query.ToList(); // this will force query execution!
var orderByMethod = sortingInfo.SortOrder == SortOrder.Asc
? typeof(Enumerable).GetMethods().First(m => m.Name == "OrderBy" && m.GetParameters().Count() == 2)
: typeof(Enumerable).GetMethods().First(m => m.Name == "OrderByDescending" && m.GetParameters().Count() == 2);
orderByMethod = orderByMethod.MakeGenericMethod(typeof(T), objectProperty.PropertyType);
return Expression.Lambda<Func<IEnumerable<T>>>(Expression.Call(orderByMethod, Expression.Constant(materialisedQuery), lambda)).Compile()();
}
通过 EF 强制进行排序可能会很痛苦(如果可能的话 - 我不确定它是否允许您这样做)。
有一个参数用于在代码和数据库中对最终数据集进行排序:
- 一方面,您可以更轻松地扩展代码(RDBMS 不能很好地扩展,并且扩展有限制)
- 但是根据您的数据,您可能会发现提供订单有助于 SQL 提出更好的执行计划
推荐阅读
- javascript - 几乎递增的序列码信号
- node.js - JWT nodejs / express - 无效签名
- python - 如何执行这个 Python 包?
- java - Tomcat Docker Image 和软件的问题
- php - 从数组数组中删除键值的有效方法
- python - 为什么 tensorflow 可能要指定动态维度
- html - 移动布局中的 Divs 顺序 - Bootstrap 4 行和列
- c# - 如何使用 Mobius 在数据块中从 C# 调用笔记本或运行作业?
- python - Python3.6:文件“/usr/lib/python3.6/configparser.py”,第 1138 行,在 _unify_values
- vue.js - 不能将对象从方法传递给数据变量?