【发布时间】:2018-04-05 08:11:54
【问题描述】:
我有一个扩展方法来对我的实体进行排序,在某些情况下我需要对子集合的属性进行排序
public static IQueryable<Payment> SetSort(this IQueryable<Payment> payments, string sortProperty, string direction)
if (string.Equals(sortProperty, PaymentSortProperties.TimeStamp, StringComparison.CurrentCultureIgnoreCase))
{
return sortDirection == SortDirection.Asc ? payments.OrderBy(x => x.History.OrderBy(h=> h.Timestamp)) : payments.OrderByDescending(x => x.History.OrderByDescending(h => h.Timestamp));
}
}
从
调用 public async Task<IPagedList<Payment>> Get(int pageNumber, int pageSize, string sortProperty, string direction, string searchString)
{
var result = _data.Payments
.Include(x => x.History)
.ThenInclude(x=>x.Status)
.Filter(searchString)
.SetSort(sortProperty, direction);
return await result.ToPagedListAsync(pageNumber, pageSize);
}
我收到错误System.ArgumentException: At least one object must implement IComparable.
我见过一些例子表明我会这样做
if (string.Equals(sortProperty, PaymentSortProperties.TimeStamp, StringComparison.CurrentCultureIgnoreCase))
{
return sortDirection == SortDirection.Asc ?
payments.OrderBy(x => x.History.Min(h=> h.Timestamp))
: payments.OrderByDescending(x => x.History.Max(h => h.Timestamp));
}
但这会触发SELECT n + 1 查询(即导致将dB 中的所有实体加载到内存中,然后进行排序)。
正确的做法是什么?
【问题讨论】:
-
有更好的方法来动态添加排序表达式,这里只是众多示例之一:stackoverflow.com/a/36303246/861716。但这并不能解决您的直接问题,即(可能)您正在尝试输入一个带点的名称。您没有显示您尝试排序的属性,所以我们必须猜测。
-
我试图排序的属性是 History 集合上的 Timestamp,它位于第一个代码块中。
-
啊,是的。根据
x => x.History.OrderBy(h=> h.Timestamp)的结果排序应该是什么样子的? -
付款按历史集合中最早的时间戳排序(使用 OrderBy 时)
-
您正在尝试订购收藏品就是我的意思。仔细看看你的代码做了什么。
标签: c# .net entity-framework entity-framework-core ef-core-2.0