Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# AsQueryable()的用途是什么?_C#_.net_Linq_Ienumerable_Iqueryable - Fatal编程技术网

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
    。这允许您避免编写两个不同版本的非常通用的助手方法

  • 它允许您将queryable的编译时类型更改为
    IQueryable
    ,而不是其他派生类型。实际上;您可以在
    IQueryable
    上使用它,同时在
    IEnumerable
    上使用
    AsEnumerable
    。您可能有一个实现
    IQueryable
    的对象,但它也有一个实例
    Select
    方法。如果是这种情况,并且希望使用LINQ
    Select
    方法,则需要将对象的编译时类型更改为
    IQueryable
    。您可以强制转换它,但是通过使用
    AsQueryable
    方法,您可以利用类型推断。如果泛型参数列表很复杂,那么这就更方便了,如果任何泛型参数都是匿名类型,那么这实际上是必要的


  • 正如sanjuro所指出的,AsQueryable()的用途在中进行了解释。该条特别指出

    这在真实的word场景中提供了极好的好处,在这些场景中,实体上有某些方法返回T的IQueryable和一些方法返回列表。但是,您需要在所有集合上应用业务规则筛选器,而不管集合是作为IQueryable of T还是IEnumerable of T返回的,如果集合实现IQueryable,那么您确实希望利用在数据库上执行业务筛选器,否则,请使用Linq对委托的对象实现在内存中应用业务筛选器


    你介意换一句话吗:“那是d