Jaki jest cel AsQueryable ()?
Jest celem AsQueryable()
tylko po to, aby można było przekazać IEnumerable
metodom, które mogą się spodziewać IQueryable
, czy jest jakiś użyteczny powód, aby reprezentować IEnumerable
jako IQueryable
? Na przykład, czy ma to być dla takich przypadków:
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();
}
A może faktycznie sprawia, że robi coś innego:
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();
Czy wersje tych metod rozszerzeń po prostu budują wyrażenie, które robi to samo po wykonaniu? Moje główne pytanie brzmi, co to jest prawdziwy przypadek użycia AsQueryable
?
5 answers
Istnieje kilka głównych zastosowań.
Jak wspomniano w innych odpowiedziach, można go użyć do wyśmiewania źródła danych z zapytań za pomocą źródła danych w pamięci, dzięki czemu można łatwiej testować metody, które ostatecznie zostaną użyte na bazie nieujemnej
IQueryable
.Można pisać metody pomocnicze do manipulowania kolekcjami, które mogą być stosowane do sekwencji w pamięci lub zewnętrznych źródeł danych. Jeśli piszesz swoje metody pomocy do wykorzystania
IQueryable
w całości możesz po prostu użyćAsQueryable
na wszystkich enumerable, aby ich używać. Pozwala to uniknąć pisania dwóch oddzielnych wersji bardzo uogólnionych metod pomocniczych.Pozwala zmienić typ czasu kompilacji zapytania na
IQueryable
, a nie na typ Pochodny. W efekcie; użyłbyś go naIQueryable
w tym samym czasie, w którym użyłbyśAsEnumerable
naIEnumerable
. Możesz mieć obiekt implementujący metodęIQueryable
, ale również instancję metodySelect
. Gdyby tak było, a chcielibyście skorzystać z Metoda LINQSelect
, trzeba by zmienić typ czasu kompilacji obiektu naIQueryable
. Możesz go po prostu rzucić, ale mając metodęAsQueryable
możesz skorzystać z wnioskowania typu. Jest to po prostu wygodniejsze, jeśli ogólna lista argumentów jest złożona i jest to w rzeczywistości konieczne , jeśli którykolwiek z ogólnych argumentów jest anonimowym typem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-04 15:24:54
Najodpowiedniejszy przypadek jaki mam dla AsQueryable to testy jednostkowe. Powiedzmy, że mam następujący nieco wymyślony przykład
public interface IWidgetRepository
{
IQueryable<Widget> Retrieve();
}
public class WidgetController
{
public IWidgetRepository WidgetRepository {get; set;}
public IQueryable<Widget> Get()
{
return WidgetRepository.Retrieve();
}
}
I chcę napisać test jednostkowy, aby upewnić się, że kontroler przekazuje wyniki zwrócone z repozytorium. Wyglądałoby to mniej więcej tak:
[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));
}
Gdzie tak naprawdę, cała Metoda AsQueryable() pozwala mi zrobić to zadowolić kompilator podczas konfigurowania makiety.
Byłbym ciekaw, gdzie jest to używane w kodzie aplikacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-04 12:45:28
Jak zauważył sanjuro, cel asqueryable() jest wyjaśniony w używając AsQueryable z Linq do obiektów i Linq do SQL. W szczególności artykuł stwierdza,
To oferuje doskonałe korzyści w rzeczywistych scenariuszach word, gdzie masz pewne metody na encji, które zwracają IQueryable z T i niektóre metody zwracają listę. Ale wtedy masz filtr reguł biznesowych, który musi być zastosowany na całej kolekcji, niezależnie od tego, czy kolekcja jest zwracana jako IQueryable z t lub IEnumerable T. Z punktu widzenia wydajności, naprawdę chcesz wykorzystać wykonywanie filtra biznesowego w bazie danych, jeśli kolekcja implementuje IQueryable, w przeciwnym razie wróć do zastosowania filtra biznesowego w pamięci za pomocą Linq do obiektowej implementacji delegatów.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-04 23:38:43
Interfejs IQueryable
cytowanie dokumentacji:
Interfejs IQueryable jest przeznaczony do implementacji poprzez zapytanie dostawcy.
Więc dla kogoś, kto zamierza zrobić swoje datastracture queryable w. NET, że datastruktura , które nie są konieczne, może być wyliczona lub mieć ważny enumerator .
IEnumerator
jest interfejsem do iteracji i przetwarzania strumienia danych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-28 14:27:20
Cel asqueryable() jest znacznie wyjaśniony w tym artykule Używanie AsQueryable z Linq to Objects i Linq To SQL
Z sekcji Uwagi MSDN Queryable.Metoda AsQueryable:
Jeśli typ źródła implementuje IQueryable, AsQueryable (IEnumerable) zwraca go bezpośrednio. W przeciwnym razie zwraca IQueryable, który wykonuje zapytania, wywołując równoważne metody operatora zapytań w Enumerable zamiast tych w Queryable.
To jest dokładnie to, co jest wspomniane i użyte w powyższym artykule. W twoim przykładzie, to zależy od tego, co jest orderRepo.GetAll returning, IEnumerable lub IQueryable (Linq to Sql). Jeśli zwróci IQueryable, metoda Count() zostanie wykonana w bazie danych, w przeciwnym razie zostanie wykonana w pamięci. Przyjrzyj się uważnie przykładowi w cytowanym artykule.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-04 15:13:49