我在我的.NET Core 2.2应用程序上使用EF Core与DB连接,并在前端使用Angular 8。我还使用 OData 从我的 API 中检索一些数据。
我的 OData 查询如下所示:
https://example.com/Odata/Farmers?$count=true&$orderby=firstName%20asc&$top=10
上面的查询返回排序如下的数据:A, B, a, b
但它应该返回类似(不区分大小写(的数据:A, a, B, b.
我的 .NET Core API 终结点如下所示:
[EnableQuery(HandleNullPropagation = HandleNullPropagationOption.False)]
[ODataRoute]
[AuthorizeScopes(AppScopes.FarmerListRead)]
[HttpGet]
public IQueryable<FarmerViewDto> GetAll()
{
return _unitOfWork
.FarmerViewRepository
.GetAllQueryable()
.UseAsDataSource()
.For<FarmerViewDto>();
}
我在 OData 路由配置中找到了一个属性EnableCaseInsensitive
,但它用于其他用途。我找不到适合我的问题的解决方案。
尝试这样的事情...
public class CaseInsensitiveComparer : IComparer<string>
{
public int Compare(string a, string b)
{
return string.Compare(a, b, StringComparison.OrdinalIgnoreCase);
}
}
[EnableQuery(HandleNullPropagation = HandleNullPropagationOption.False)]
[ODataRoute]
[AuthorizeScopes(AppScopes.FarmerListRead)]
[HttpGet]
public IQueryable<FarmerViewDto> GetAll()
{
return _unitOfWork
.FarmerViewRepository
.GetAllQueryable()
.UseAsDataSource()
.For<FarmerViewDto>();
.OrderBy(x => x.firstName, new CaseInsensitiveComparer());
}
== 编辑 ==
以下可查询扩展支持按单个列名按升序或降序排序(默认为升序(...
namespace System.Linq
{
public static class QueryableExtensions
{
public static IOrderedQueryable<TSource> Sort<TSource>(this IQueryable<TSource> source, IComparer<string> comparer, string sortExpression)
{
bool sortDescending = false;
if (sortExpression.EndsWith(" DESC", StringComparison.OrdinalIgnoreCase))
{
sortDescending = true;
sortExpression = sortExpression.Substring(0, sortExpression.Length - 5);
}
if (sortExpression.EndsWith(" ASC", StringComparison.OrdinalIgnoreCase))
{
sortDescending = false;
sortExpression = sortExpression.Substring(0, sortExpression.Length - 4);
}
var param = Expression.Parameter(typeof(TSource), "source");
var expression = Expression.Lambda<Func<TSource, string>>(Expression.Convert(Expression.Property(param, sortExpression), typeof(string)), param);
if (!sortDescending)
return source.OrderBy<TSource, string>(expression, comparer);
else
return source.OrderByDescending<TSource, string>(expression, comparer);
}
}
}
然后您可以通过以下方式使用它...
return _unitOfWork
.FarmerViewRepository
.GetAllQueryable()
.UseAsDataSource()
.For<FarmerViewDto>();
.Sort(new CaseInsensitiveComparer(), "firstName asc");
它假定所有对象属性都可以合理地转换为字符串。如果属性上有自定义类,则需要确保正确覆盖ToString()
类。
此外,它仅适用于单个字段,即:"field"
,"field1 asc"
或"field1 desc"
。如果你想要像"field1 asc, field2 desc"
这样的东西,我会把额外的愚蠢留给你.
在你做返回之前
var farmerViewDto = _unitOfWork
.FarmerViewRepository
.GetAllQueryable()
.UseAsDataSource()
.For<FarmerViewDto>();
var returnValue = farmerViewDto.ToList().OrderBy(x => x.PropertyYouWantToSort, StringComparer.OrdinalIgnoreCase).AsQueryable();
retur returnValue;
在我的评论中添加其他信息 更快但代码很多
var searchFilter = //user input
var query = _unitOfWork
.FarmerViewRepository
.GetAllQueryable()
.UseAsDataSource()
.For<FarmerViewDto>().AsQueryable();
if (searchFilter == "property1")
{
query = query.OrdberBy(x => x.Property1, StringComparer.OrdinalIgnoreCase).AsQueryable();
}
if (searchFilter == "property2")
{
query = query.OrdberBy(x => x.Property2, StringComparer.OrdinalIgnoreCase).AsQueryable();
}
.....
return query;
通过反射
var searchFilter = //user input
var query = _unitOfWork
.FarmerViewRepository
.GetAllQueryable()
.UseAsDataSource()
.For<FarmerViewDto>();
query.Where(x => x.GetType()
.GetProperty(searchFilter)
.GetValue(x).ToString(), StringComparer.OrdinalIgnoreCase).AsQueryable();
return query;