如何使 IQueryable 可重用和可链接?
How to make IQueryable reusable and chainable?
我想我在这里有点困惑。
我的 EF 项目有一些存储库和服务。我希望能够使用 IQueryable 对我的任何模型进行分页。
我的存储库包含一个方法 returns IQueryable:
public IQueryable<TEntity> GetQuery()
{
return EntitySet;
}
我还有一个查询对象,我打算将其用于可重用查询。是这样的:
public static class CarQuery
{
public static IQueryable<Car> RegisteredCars(this IQueryable<car> car, int userId)
{
return car.Where(r => r.RegisteredUser.UserId == userId);
}
public static IQueryable<car> WithStockAvailability(this IQueryable<car> car, bool isAvailable)
{
return car.Where(r => r.IsInStock == isAvailable);
}
}
我正在我的服务层中使用它,如下所示:
public IEnumerable<Car> GetUserRegisteredCarsInStock(int userId, int? pageNumber, int? pageSize)
{
var query = _repository.GetQuery();
query = query.RegisteredCars(userId);
query = query.WithStockAvailability(true);
if (pageSize.HasValue && pageNumber.HasValue)
{
return .OrderByDescending(r => r.carId) // for some reason if I don't have the order, the query fails
.Skip(pageNumber.Value * pageSize.Value)
.Take(pageSize.Value);
}
return query.ToList();
}
但我认为我这样做不对。特别是这一行:
query = query.RegisteredCars(userId);
query = query.WithStockAvailability(true);
如何使它看起来像这样:
query.RegisteredCars(userId)
.WithStockAvailability(true)
.Page(pageNumber, pageSize);
谢谢
只要您创建了 Page
扩展方法,该行应该可以工作。
您可以修改 Page
方法以包含这样的 order by 子句:
public static IQueryable<T> Page<T, TKey>(this IQueryable<T> source,
Expression<Func<T, TKey>> orderExpression,
int pageNumber, int pageSize)
{
return source.OrderBy(orderExpression)
.Skip(pageNumber * pageSize)
.Take(pageSize);
}
你这样调用方法:
query = query.Page(r => r.CarId, pageNumber, pageSize);
您已经完成了前两个。
IQueryable<car> query = _repository.GetQuery()
.RegisteredCars(userId)
.WithStockAvailability(true);
Paging 只需要一个通用的扩展函数,它需要一个 ordered query:
public static IQueryable<T> Paging(this IOrderedQueryable<T> query,
int? pageSize,
int? pageNumber)
{
if (pageSize.HasValue && pageNumber.HasValue)
{
return query.Skip(pageNumber.Value * pageSize.Value)
.Take(pageSize.Value);
}
return query;
}
所以现在您可以将整个事情链接起来:
IQueryable<car> query = _repository.GetQuery()
.RegisteredCars(userId)
.WithStockAvailability(true)
.OrderByDescending(c => c.carId)
.Paging(pageSize, pageNumber);
我想我在这里有点困惑。
我的 EF 项目有一些存储库和服务。我希望能够使用 IQueryable 对我的任何模型进行分页。
我的存储库包含一个方法 returns IQueryable:
public IQueryable<TEntity> GetQuery()
{
return EntitySet;
}
我还有一个查询对象,我打算将其用于可重用查询。是这样的:
public static class CarQuery
{
public static IQueryable<Car> RegisteredCars(this IQueryable<car> car, int userId)
{
return car.Where(r => r.RegisteredUser.UserId == userId);
}
public static IQueryable<car> WithStockAvailability(this IQueryable<car> car, bool isAvailable)
{
return car.Where(r => r.IsInStock == isAvailable);
}
}
我正在我的服务层中使用它,如下所示:
public IEnumerable<Car> GetUserRegisteredCarsInStock(int userId, int? pageNumber, int? pageSize)
{
var query = _repository.GetQuery();
query = query.RegisteredCars(userId);
query = query.WithStockAvailability(true);
if (pageSize.HasValue && pageNumber.HasValue)
{
return .OrderByDescending(r => r.carId) // for some reason if I don't have the order, the query fails
.Skip(pageNumber.Value * pageSize.Value)
.Take(pageSize.Value);
}
return query.ToList();
}
但我认为我这样做不对。特别是这一行:
query = query.RegisteredCars(userId);
query = query.WithStockAvailability(true);
如何使它看起来像这样:
query.RegisteredCars(userId)
.WithStockAvailability(true)
.Page(pageNumber, pageSize);
谢谢
只要您创建了 Page
扩展方法,该行应该可以工作。
您可以修改 Page
方法以包含这样的 order by 子句:
public static IQueryable<T> Page<T, TKey>(this IQueryable<T> source,
Expression<Func<T, TKey>> orderExpression,
int pageNumber, int pageSize)
{
return source.OrderBy(orderExpression)
.Skip(pageNumber * pageSize)
.Take(pageSize);
}
你这样调用方法:
query = query.Page(r => r.CarId, pageNumber, pageSize);
您已经完成了前两个。
IQueryable<car> query = _repository.GetQuery()
.RegisteredCars(userId)
.WithStockAvailability(true);
Paging 只需要一个通用的扩展函数,它需要一个 ordered query:
public static IQueryable<T> Paging(this IOrderedQueryable<T> query,
int? pageSize,
int? pageNumber)
{
if (pageSize.HasValue && pageNumber.HasValue)
{
return query.Skip(pageNumber.Value * pageSize.Value)
.Take(pageSize.Value);
}
return query;
}
所以现在您可以将整个事情链接起来:
IQueryable<car> query = _repository.GetQuery()
.RegisteredCars(userId)
.WithStockAvailability(true)
.OrderByDescending(c => c.carId)
.Paging(pageSize, pageNumber);