我应该在我的界面中指定 IQueryable over List 吗?

Should I be specifying IQueryable over List in my interfaces?

我想知道,在定义我的界面时,对于对象组,我是否应该更喜欢 IQueryable 而不是 List。或者也许 IEnumerable 更好,因为 IEnumerable 类型可以转换为 IQueryable 以便与 LINQ 一起使用。

我正在看一门在线课程,它正在处理 EntityFramework,最好使用 IQueryable,因为 LINQ 使用它(好吧,它不止于此,但现在可能不重要) . 使用了下面的代码,它让我思考是否应该为我的对象组指定 IQueryable 而不是 List。

namespace eManager.Domain
{
    public interface IDepartmentDataSource
    {
        IQueryable<Employee> Employees { get; }
        IQueryable<Department> Departments { get; }
    }

如果我正在为调用存储库获取员工的服务构建接口,我通常会指定

List <Employees> 

但这是最​​佳做法吗? IQueryable 会为实现我的接口的 类 提供更大的灵活性吗?如果他们不需要 LINQ(假设他们只想要一个列表),那么必须导入 LINQ 的开销又如何呢?我应该对这两个都使用 IEnumerable 吗?

IQueryable 接口实际上是对尚未执行的 Entity Framework 的查询。当您在 IQueryable 上调用 ToList()First()FirstOrDefault() 等时,Entity Framework 将构造 SQL 查询并查询数据库。

IEnumerable 另一方面是 'just' 集合的枚举器。您可以使用它来过滤集合,但您会使用 LINQ to Objects。 Entity Framework 在这里没有发挥作用。

回答您的问题:视情况而定。如果您希望您的存储库的客户端能够进一步自定义他们可以执行的查询,您应该公开 IQueryable,但是如果您希望在您的存储库中完全控制如何查询数据库,您可以使用 IEnumerable.

我更喜欢使用 IEnumerable,因为这样不会在整个应用程序中泄漏对 Entity Framework 的使用。存储库负责数据库访问。进行 LINQ to EF 优化也更容易,因为查询仅在存储库中。

我通常做的是制作存储库return IQueryable。然后在 BL 中我指定 IEnumerableIQueryble。了解 IQuerybleIEnumerable 之间的主要区别很重要。

假设您将数据提取到 IEnumerable 中 IEnumerable employees=this.repository.GetAll(); 现在假设这个特定的功能只需要21岁以上的员工,其他的根本不需要。

你会这样做: employees.Where(a=>a.Age>21) 在这种情况下,原始查询将加载到内存中,然后将应用 Where。

现在假设您更改函数以将数据提取到 IQueryable 中 IQueryable employees=this.repository.GetAll(); employees.Where(a=>a.Age>21) 这次当您使用 Where 子句修改查询时,整个查询将在数据库中执行(如果可能)并且您只会从数据库中获取年龄超过 21 岁的员工。

在 IEnumerable 的情况下,您将从数据库中获取所有员工,然后他们将在内存中进行筛选以满足 where 条件。

使用 IEnumerable、IList 或其他? 如果您知道将对集合执行哪些操作,您可以轻松选择要使用的接口。基本上,如果您将只迭代您将使用 IEnumerable 的集合。如果您要进行更多操作,则需要选择合适的界面。在 pluralsight 中有很好的 .NET 集合视频。