如何使IQueryable可重复使用和可链接?

时间:2016-01-14 16:23:23

标签: entity-framework iqueryable

我想我在这里有点困惑。

我的EF项目中有一些存储库和服务。我希望能够使用IQueryable对我的任何模型进行分页。

我的存储库包含一个返回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);

由于

2 个答案:

答案 0 :(得分:2)

只要您创建了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);

答案 1 :(得分:1)

你已经完成了前两个。

IQueryable<car> query = _repository.GetQuery()
                                   .RegisteredCars(userId)
                                   .WithStockAvailability(true);

分页只需要一个通用的扩展函数,它需要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);