AsQueryable ()의 목적은 무엇입니까?


107

그 목적은 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();
}

또는 실제로 다른 작업을 수행합니까?

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();

IQueryable이러한 확장 메서드 의 버전은 일단 실행되면 동일한 작업을 수행하는 Expression을 구축합니까? 내 주요 질문은 사용에 대한 실제 사용 사례는 AsQueryable무엇입니까?

답변:


65

몇 가지 주요 용도가 있습니다.

  1. 다른 답변에서 언급했듯이 메모리 내 데이터 소스를 사용하여 쿼리 가능한 데이터 소스를 모의하는 데 사용할 수 있으므로 결국 열거 불가능 기반에서 사용될 메서드를 더 쉽게 테스트 할 수 있습니다 IQueryable.

  2. 메모리 내 시퀀스 또는 외부 데이터 소스에 적용 할 수있는 컬렉션을 조작하기위한 도우미 메서드를 작성할 수 있습니다. IQueryable완전히 사용할 도움말 메서드를 작성하는 경우 AsQueryable모든 열거 형에 사용하여 사용할 수 있습니다. 이렇게하면 매우 일반화 된 도우미 메서드의 두 가지 개별 버전을 작성하지 않아도됩니다.

  3. 이를 통해 쿼리 가능의 컴파일 시간 유형을 IQueryable더 파생 된 유형이 아닌 으로 변경할 수 있습니다 . 사실상; 당신은 그것을 사용하는 거라고 IQueryable당신이 사용하는 거라고 같은 시간에 AsEnumerableIEnumerable. 구현하는 객체가있을 수 IQueryable있지만 인스턴스 Select메서드도 있습니다. 이 경우 LINQ Select메서드 를 사용하려는 경우 개체의 컴파일 시간 유형을 IQueryable. 그냥 캐스팅 할 수 있지만 AsQueryable메서드를 사용하면 유형 추론을 활용할 수 있습니다. 이것은 제네릭 인수 목록이 복잡 할 때 더 편리 하고 제네릭 인수가 익명 유형 인 경우 실제로 필요 합니다.


부흥에 감사드립니다. 가장 완전하기 때문에 이것을 답으로 표시하십시오.
Ocelot20 2013

5
IQueryable<T>에서 파생 된다는 점을 감안할 때 IEnumerable<T>"비 열거 형 기반 IQueryable"이 의미하는 바를 설명해 주시겠습니까?
Dai

2
@Dai 그것은 IQueryable단순히 래핑 된 것 이상의 의미를 가지고 있으며 IEnumerable실제로 IQueryable.
Servy

# 1은 정확히 내가 찾던 것입니다. 확인 해주셔서 감사합니다.
one.beat.consumer

12

AsQueryable에 대한 가장 유효한 사례는 단위 테스트입니다. 다음과 같은 다소 인위적인 예가 있다고 가정하십시오.

public interface IWidgetRepository
{
   IQueryable<Widget> Retrieve();
} 

public class WidgetController
{
   public IWidgetRepository WidgetRepository {get; set;}


   public IQueryable<Widget> Get()
   {
      return WidgetRepository.Retrieve();
   }
}

컨트롤러가 저장소에서 반환 된 결과를 다시 전달하는지 확인하기 위해 단위 테스트를 작성하고 싶습니다. 다음과 같이 보일 것입니다.

[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));
}

실제로 모든 AsQueryable () 메서드를 사용하면 mock을 설정할 때 컴파일러를 만족시킬 수 있습니다.

그래도 응용 프로그램 코드에서 이것이 사용되는 곳에 관심이 있습니다.


11

sanjuro가 언급했듯이 AsQueryable ()의 목적은 Using AsQueryable With Linq To Objects And Linq To SQL에 설명되어 있습니다. 특히 기사는 다음과 같이 말합니다.

이는 T의 IQueryable을 반환하는 엔터티에 특정 메서드가 있고 일부 메서드는 List를 반환하는 실제 단어 시나리오에서 탁월한 이점을 제공합니다. 그러나 컬렉션이 T의 IQueryable 또는 T의 IEnumerable로 반환되는지 여부에 관계없이 모든 컬렉션에 적용해야하는 비즈니스 규칙 필터가 있습니다. 컬렉션은 IQueryable을 구현하고 그렇지 않으면 Linq를 사용하여 메모리에 비즈니스 필터를 적용하여 대리자의 개체 구현에 적용합니다.


6

AsQueryable ()의 목적은이 기사에서 Linq To Objects 및 Linq To SQL과 함께 AsQueryable 사용하기에서 자세히 설명합니다.

MSDN Queryable.AsQueryable 메서드의 설명 섹션에서 :

소스 유형이 IQueryable을 구현하는 경우 AsQueryable (IEnumerable)은이를 직접 반환합니다. 그렇지 않으면 Queryable에서 대신 Enumerable에서 동등한 쿼리 연산자 메서드를 호출하여 쿼리를 실행하는 IQueryable을 반환합니다.

그것이 바로 위의 기사에서 언급되고 사용 된 것입니다. 귀하의 예에서는 orderRepo.GetAll 반환, IEnumerable 또는 IQueryable (Linq to Sql)에 따라 다릅니다. IQueryable을 반환하면 Count () 메서드가 데이터베이스에서 실행되고 그렇지 않으면 메모리에서 실행됩니다. 참조 된 기사의 예를주의 깊게 살펴보십시오.


3

인터페이스 IQueryable인용 문서 :

IQueryable 인터페이스는 쿼리 공급자가 구현하기위한 것입니다.

따라서 데이터 구조 .NET에서 쿼리 가능하게 만들려는 사람 에게는 필요하지 않은 데이터 구조 를 열거하거나 유효한 열거자를 가질 수 있습니다 .

IEnumerator대신 데이터 스트림 을 반복하고 처리하기위한 인터페이스입니다 .


"필요하지 않은 데이터 구조는 열거되거나 유효한 열거자를 가질 수 있습니다."라고 다시 표현해 주시겠습니까? 나는 사이의 차이 이해 IQueryableIEnumerable,하지만 난에 대한 사용 사례 이해하지 못하는 AsQueryable확장 방법을. 나는 그 문장에서 약간 넘어지고 있는데, 내가 찾고있는 대답을 가질 수 있다고 생각합니다 (upvotes를 기반으로 함).
Ocelot20

Ocelot20 @ : 평균 모자 자료 구조가 공급자에 의해 제시된 것을 구현 된 IQueryable는 것을 할 수있다 열거 cappability을 제공하지. 제공자에게 달려 있습니다. Quoting doc : "Enumerable 결과를 반환하지 않는 쿼리는 Execute 메서드가 호출 될 때 실행됩니다."
Tigran 2013-06-28

분명한 것을 놓치고 있지만 "왜 사용해야 AsQueryable()하나요?"에 대한 답을 찾을 수 없습니다. 내가있어 경우 시작 를 IEnumerable (열거 기능을 제공하는 이미 수있는 뭔가)와, 왜로 변환 할 필요가 IQueryable확장 방법을 사용하여 AsQueryable()? 이것이 유용한 곳을 설명하는 작은 코드 예제일까요? 설명에 뭔가 빠진 것 같습니다. 시간 내 줘서 고마워.
Ocelot20 2013-06-28

@ Ocelot20 : 쿼리 공급자를 작성하는 데 필요한 차이점을 실제로 보여주기 위해. 당신은 우리가 알고 linq to sql, linq to xml당신이 쓰기 원한다면 .. 그래서 및 linq드라이버 목표 것을 당신의 데이터 strucutres ( linq to your data당신의 API의 사용자가 실행할 수있는 가능성이 있도록) linq에 대한 쿼리를 사용자의 데이터 구조를, 당신이 선택해야IQueryable
티그

2
당신은 차이를 설명 할 것 IQueryable등을 IEnumerable. 나는 그 차이를 알고 있으며 그것이 내가 요구하는 것이 아닙니다. 누군가를 구현하는 것을 취하고 확장 방법을 사용하여 IEnumerable변환 하려는 이유를 묻습니다 . 그게 당신이 대답하는 것입니까? 난 아직 말할 수 없다 ..IQueryableAsQueryable
Ocelot20
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.