有没有办法卡住 IQueryable
,以便在访问数据库时不会向查询添加额外的连接?例如,我可以执行 .ToList()
来卡住查询,但这会影响性能,因为我所做的任何过滤都在中间层进行,并且我没有从预过滤中获得任何性能提升在数据库服务器上过滤?
为清楚起见编辑:
我有一个 OData 服务,它返回一个 IQueryable
,客户端可以根据需要过滤/排序/投影。我只是想阻止他们提取更多数据。我可以通过执行 ToList().AsQueryable()
来做到这一点,但这失去了 lazyLoading 的优势,并且失去了允许客户端过滤请求的全部目的。
我查看的一个选项是设置:EnableQueryAttribute.AllowedQueryOptions
以排除 Expand
,但是即使我的初始查询已扩展,客户端仍然无法访问选择那些部分。
最佳答案
我假设您实际上有一个 IQueryable<T>
而不是 IQueryable
.
如果您不希望您的客户访问所有 IQueryable<T>
方法,不要返回 IQueryable<T>
.由于您希望他们只能过滤/排序/项目,因此创建一个包含 IQueryable<T>
的对象但只公开所需的方法,并使用它:
public interface IDataResult<T>
{
IDataResult<T> FilterBy(Expression<Func<T, bool>> predicate);
IDataResult<TResult> ProjectTo<TResult>(Expression<Func<T, TResult>> predicate);
IDataResult<T> SortBy<TKey>(Expression<Func<T, TKey>> keySelector);
IDataResult<T> SortByDescending<TKey>(Expression<Func<T, TKey>> keySelector);
List<T> ToList();
IEnumerable<T> AsEnumerable();
}
public class DataResult<T> : IDataResult<T>
{
private IQueryable<T> Query { get; set; }
public DataResult(IQueryable<T> originalQuery)
{
this.Query = originalQuery;
}
public IDataResult<T> FilterBy(Expression<Func<T, bool>> predicate)
{
return new DataResult<T>(this.Query.Where(predicate));
}
public IDataResult<T> SortBy<TKey>(Expression<Func<T, TKey>> keySelector)
{
return new DataResult<T>(this.Query.OrderBy(keySelector));
}
public IDataResult<T> SortByDescending<TKey>(Expression<Func<T, TKey>> keySelector)
{
return new DataResult<T>(this.Query.OrderByDescending(keySelector));
}
public IDataResult<TResult> ProjectTo<TResult>(Expression<Func<T, TResult>> predicate)
{
return new DataResult<TResult>(this.Query.Select(predicate));
}
public List<T> ToList()
{
return this.Query.ToList();
}
public IEnumerable<T> AsEnumerable()
{
return this.Query.AsEnumerable();
}
}
通过这种方式,您还可以防止 EF 和 DB 相关依赖项在您的应用程序中蔓延。 IQueryable<T>
上的任何更改方法将包含在此类中,而不是遍布各处。
关于c# - 卡住 linq IQueryable(就像 ToList().AsQueryable() 会做的那样),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30770017/