C# AsQueryable()的用途是什么?
C# AsQueryable()的用途是什么?,c#,.net,linq,ienumerable,iqueryable,C#,.net,Linq,Ienumerable,Iqueryable,AsQueryable()的目的是为了将IEnumerable传递给可能期望IQueryable的方法,还是有一个有用的理由将IEnumerable表示为IQueryable?例如,它是否适用于这样的情况: IEnumerable<Order> orders = orderRepo.GetAll(); // I don't want to create another method that works on IEnumerable, // so I convert it here
AsQueryable()
的目的是为了将IEnumerable
传递给可能期望IQueryable
的方法,还是有一个有用的理由将IEnumerable
表示为IQueryable
?例如,它是否适用于这样的情况:
IEnumerable<Order> orders = orderRepo.GetAll();
// I don't want to create another method that works on IEnumerable,
// so I convert it here.
CountOrders(orders.AsQueryable());
public static int CountOrders(IQueryable<Order> ordersQuery)
{
return ordersQuery.Count();
}
[TestMethod]
public void VerifyRepositoryOutputIsReturned()
{
var widget1 = new Widget();
var widget2 = new Widget();
var listOfWidgets = new List<Widget>() {widget1, widget2};
var widgetRepository = new Mock<IWidgetRepository>();
widgetRepository.Setup(r => r.Retrieve())
.Returns(listOfWidgets.AsQueryable());
var controller = new WidgetController();
controller.WidgetRepository = widgetRepository.Object;
var results = controller.Get();
Assert.AreEqual(2, results.Count());
Assert.IsTrue(results.Contains(widget1));
Assert.IsTrue(results.Contains(widget2));
}
IEnumerable orders=orderepo.GetAll();
//我不想创建另一个对IEnumerable有效的方法,
//所以我在这里转换它。
CountOrders(orders.AsQueryable());
公共静态int CountOrders(IQueryable ordersQuery)
{
return ordersQuery.Count();
}
或者它确实让它做了一些不同的事情:
IEnumerable<Order> orders = orderRepo.GetAll();
IQueryable<Order> ordersQuery = orders.AsQueryable();
IEnumerable<Order> filteredOrders = orders.Where(o => o.CustomerId == 3);
IQueryable<Order> filteredOrdersQuery = ordersQuery.Where(o => o.CustomerId == 3);
// Are these executed in a different way?
int result1 = filteredOrders.Count();
int result2 = filteredOrdersQuery.Count();
IEnumerable orders=orderepo.GetAll();
IQueryable ordersQuery=orders.AsQueryable();
IEnumerable filteredOrders=订单。其中(o=>o.CustomerId==3);
IQueryable filteredOrdersQuery=ordersQuery.Where(o=>o.CustomerId==3);
//这些是以不同的方式执行的吗?
int result1=filteredOrders.Count();
int result2=filteredOrdersQuery.Count();
这些扩展方法的
IQueryable
版本是否只构建了一个表达式,一旦执行该表达式,它就会执行相同的操作?我的主要问题是,使用AsQueryable
的真正用例是什么?接口IQueryable
引用文档:
IQueryable接口旨在通过查询实现
提供者
因此,对于打算在.NET中查询其数据结构的人,可以枚举不必要的数据结构或使用有效的枚举器
IEnumerator
是一个用于迭代和处理数据流的接口。我对AsQueryable最有效的例子是单元测试。假设我有下面这个有点做作的例子
public interface IWidgetRepository
{
IQueryable<Widget> Retrieve();
}
public class WidgetController
{
public IWidgetRepository WidgetRepository {get; set;}
public IQueryable<Widget> Get()
{
return WidgetRepository.Retrieve();
}
}
公共接口IWidgetRepository
{
IQueryable检索();
}
公共类WidgetController
{
公共IWidgetRepository WidgetRepository{get;set;}
公共IQueryable Get()
{
返回WidgetRepository.Retrieve();
}
}
我想编写一个单元测试,以确保控制器传回从存储库返回的结果。看起来是这样的:
IEnumerable<Order> orders = orderRepo.GetAll();
// I don't want to create another method that works on IEnumerable,
// so I convert it here.
CountOrders(orders.AsQueryable());
public static int CountOrders(IQueryable<Order> ordersQuery)
{
return ordersQuery.Count();
}
[TestMethod]
public void VerifyRepositoryOutputIsReturned()
{
var widget1 = new Widget();
var widget2 = new Widget();
var listOfWidgets = new List<Widget>() {widget1, widget2};
var widgetRepository = new Mock<IWidgetRepository>();
widgetRepository.Setup(r => r.Retrieve())
.Returns(listOfWidgets.AsQueryable());
var controller = new WidgetController();
controller.WidgetRepository = widgetRepository.Object;
var results = controller.Get();
Assert.AreEqual(2, results.Count());
Assert.IsTrue(results.Contains(widget1));
Assert.IsTrue(results.Contains(widget2));
}
[TestMethod]
公共无效验证RepositoryOutputisReturn()
{
var widget1=newwidget();
var widget2=新小部件();
var listOfWidgets=new List(){widget1,widget2};
var widgetRepository=new Mock();
widgetRepository.Setup(r=>r.Retrieve())
.Returns(listOfWidgets.AsQueryable());
var controller=新的WidgetController();
controller.WidgetRepository=WidgetRepository.Object;
var results=controller.Get();
arest.AreEqual(2,results.Count());
IsTrue(results.Contains(widget1));
IsTrue(results.Contains(widget2));
}
实际上,AsQueryable()方法允许我在设置模拟时满足编译器的要求
不过,我对应用程序代码中使用AsQueryable()的地方很感兴趣。本文详细解释了AsQueryable()的用途
从MSDN Queryable.AsQueryable方法的备注部分:
如果源类型实现IQueryable,AsQueryable(IEnumerable)将直接返回它。否则,它将返回一个IQueryable,该IQueryable通过调用Enumerable中而不是Queryable中的等效查询运算符方法来执行查询
这正是上述文章中提到和使用的内容。
在您的示例中,这取决于orderRepo.GetAll返回的是什么、IEnumerable还是IQueryable(Linq到Sql)。如果返回IQueryable,Count()方法将在数据库上执行,否则将在内存中执行。请仔细阅读参考文章中的示例。有几个主要用途
IQueryable
上使用的方法IQueryable
,那么您可以在所有可枚举项上使用AsQueryable
。这允许您避免编写两个不同版本的非常通用的助手方法IQueryable
,而不是其他派生类型。实际上;您可以在IQueryable
上使用它,同时在IEnumerable
上使用AsEnumerable
。您可能有一个实现IQueryable
的对象,但它也有一个实例Select
方法。如果是这种情况,并且希望使用LINQSelect
方法,则需要将对象的编译时类型更改为IQueryable
。您可以强制转换它,但是通过使用AsQueryable
方法,您可以利用类型推断。如果泛型参数列表很复杂,那么这就更方便了,如果任何泛型参数都是匿名类型,那么这实际上是必要的正如sanjuro所指出的,AsQueryable()的用途在中进行了解释。该条特别指出 这在真实的word场景中提供了极好的好处,在这些场景中,实体上有某些方法返回T的IQueryable和一些方法返回列表。但是,您需要在所有集合上应用业务规则筛选器,而不管集合是作为IQueryable of T还是IEnumerable of T返回的,如果集合实现IQueryable,那么您确实希望利用在数据库上执行业务筛选器,否则,请使用Linq对委托的对象实现在内存中应用业务筛选器
你介意换一句话吗:“那是d