C# 我应该在接口中指定IQueryable over List吗?

C# 我应该在接口中指定IQueryable over List吗?,c#,interface,ienumerable,iqueryable,C#,Interface,Ienumerable,Iqueryable,我想知道,在定义接口时,对于对象组,我是否更喜欢IQueryable而不是List。或者IEnumerable更好,因为IEnumerable类型可以强制转换为IQueryable,以便与LINQ一起使用 我在网上看了一门课程,它是关于EntityFramework的,最好使用IQueryable,因为LINQ使用它(好的,还有更多内容,但现在可能不重要)。 使用了下面的代码,它让我思考是否应该为我的对象组指定IQueryable而不是List namespace eManager.Domain

我想知道,在定义接口时,对于对象组,我是否更喜欢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; }
    }
namespace eManager.Domain
{
公共接口IDepartmentDataSource
{
IQueryable雇员{get;}
IQueryable部门{get;}
}
如果我正在为调用存储库以获取员工的服务构建接口,我通常会指定

List <Employees> 
列表
但这是最佳实践吗?IQueryable会为实现我的接口的类提供更大的灵活性吗?如果它们不需要LINQ(比如它们只需要一个列表),那么必须导入LINQ的开销呢?我应该在这两个上面都使用IEnumerable吗?

该接口实际上是一个尚未执行的实体框架查询。当调用
ToList()
First()
FirstOrDefault()
时,
IQueryable
实体框架将构造SQL查询并查询数据库

另一方面,“只是”集合上的枚举数。您可以使用它筛选集合,但可以使用LINQ to对象。实体框架在这里不起作用

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


我更喜欢使用
IEnumerable
,因为这不会泄露整个应用程序对实体框架的使用。存储库负责数据库访问。对LINQ到EF进行优化也更容易,因为查询只在存储库中进行。

我通常做的是让存储库返回
IQueryabl然后在BL中指定
IEnumerable
iqueryable
。了解
iqueryable
IEnumerable
之间的主要区别很重要

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

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

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

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

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

您应该在你的问题上加上“C#”为了引起更多的关注。哦,LINQ实际上同样容易地使用
IEnumerable
。区别在于您是想提供一组调用者可以使用的数据,还是该数据的代理。就个人而言,我会选择
IEnumerable
/
IList
,除非您有特定的理由使用
IQueryable
.
IQueryable
使您的界面太宽。使您的界面比“所有员工都在这里,您想对他们做什么就做什么”更紧密:)使用
IQueryable
你给接口的实现者增加了负担。只有当有代码需要该接口时,增加负担才有意义。是否有代码会尖叫“我真的需要
IQueryable
就在这里”?@Dialogicus是的,这就是为什么我想知道IEnumerable是否是一个更好的选择。要回答你想知道的问题,一个人必须知道是否存在一个尖叫着“我真的需要
IQueryable
就在这里”的代码。只有您知道这一点,所以只有您可以回答自己的问题。如果没有这样的代码,那么可以通过简化接口来减轻负担。根据您所说的,我觉得存储库应该使用IQueryable,以便它可以使用LINQ进行查询。调用它的服务应该向其客户端返回IEnumerable。服务应该对它说客户“您向我索要了这些数据,在这里-我完成了”。任何进一步的筛选都将由客户端完成-服务不关心。是的,存储库隐式使用IQueryable,因为实体框架公开了IQueryable。当您从存储库返回项目集合时,可以从存储库返回IEnumerable。为确保不从存储库公开IQueryable您应该在IQueryable上调用ToList(),以便执行SQL查询。