2009-04-27 15 views
15

Mam metodę, która "nie ma tłumaczenie na SQL", które chcę wykonać na IQueryable, czy istnieje sposób zmusić IQueryable do wykonania bez konieczności przechowywania go w niektórych klasy pośredniej?Wymusić IQueryable do wykonania?

+0

To jest ślepy domysł, ale jeśli string.IsNullOrEmpty jest winowajcą, użyj zamiast tego dwóch klauzul where: .Where (o => o.Name! = Null) .Where (o => o.Name.Length> 0) . – mayu

Odpowiedz

25

Czy problem polega na tym, że metoda ma być uruchamiana lokalnie, a nie w bazie danych? Jeśli tak, to Twój przyjaciel to AsEnumerable. Jest to bardzo prosta metoda, coś jak:

public IEnumerable<T> AsEnumerable(IEnumerable<T> source) 
{ 
    return source; 
} 

Ważną rzeczą jest to, że sprawia, że ​​typ kompilacji rezultatu IEnumerable<T> zamiast IQueryable<T>, co oznacza żadnych operatorów zapytań LINQ zadzwonisz po tym będzie LINQ do Objects zamiast LINQ do SQL.

Na przykład:

var query = context.Employees 
        // Filtering performed in SQL 
        .Where(emp => emp.IsFullTime) 
        .AsEnumerable() 
        // Projection performed locally; ComputeSalary has no 
        // SQL equivalent 
        .Select(emp => new { Employee = emp, 
             Salary = ComputeSalary(emp) }); 

Można zadzwonić ToList jak sugeruje gdzie indziej, ale jeśli robisz filtrowanie i naprawdę nie trzeba pełną listę w pamięci, nazywając AsEnumerable i filtrowanie że Wynik będzie bardziej wydajny niż ładowanie wszystkiego w pierwszej kolejności.

+1

Czy ta technika z Linq do EF również? Wygląda na to, że tak nie jest. – neontapir

+0

Nie rozumiem, co znaczy "wykonaj lokalnie, a nie w bazie danych". Dla osób takich jak ja: IQueryable as = from a x wybierz a; następnie a.Count(); a.Foreach (...) wykona dwa zapytania SQL. – mayu

+2

@Tymek: Tak, to wykonanie dwóch zapytań SQL. Ale przez "wykonaj lokalnie" mam na myśli "pobranie wszystkich wyników w zapytaniu do tej pory z bazy danych, ale następnie wykonanie reszty zapytania w pamięci" - dzięki czemu można wykonać filtrowanie, prognozy itp., Które nie mają zastosowania w SQL. –

6
List<Employees> myEmployees = myqueryable.ToList(); 

, a następnie możesz robić swoje rzeczy linq na tej liście.

2

Otrzymujesz tę wiadomość, gdy napisałeś zapytanie, że LinqToSql nie wie, jak przetłumaczyć na SQL (co jest również tym, co mówi).

nie jestem pewien, że dostać dokładnie to, co pytasz, ale o ile widzę, masz następujące opcje:

  1. przepisać zapytanie tak, że LinqToSql może tłumaczyć to
  2. Czy jako wiele z zapytaniem, jak można na SQL Server, a następnie zajmiemy się resztą w pamięci (przy użyciu LINQ to Objects)
  3. usiąść i płakać

Zakładając, że wyklucza # 3, spójrzmy na pozostałe 2 przykłady.

  1. Przepisanie - w tym celu potrzebujemy Twojej zapytania linq.

  2. Tutaj wyjmujesz część, której nie można przetłumaczyć z pierwotnego zapytania, a następnie na Twoje wezwanie do kolorowania ToList, a następnie zastosuj resztę zapytania na tej liście.

Czy można wykonać zapytanie bez konieczności jego zapisywania? Cóż, nie do końca, zawsze można przeglądać wyniki i jako takie nie przechowywać ich w zmiennej, ale oczywiście wyniki kwerendy muszą być przechowywane gdzieś.

+1

Nie trzeba siadać, aby płakać. – mayu

+2

To prawda - jednak nie czuję, że podczas stania nikt nie powinien płakać. Jeśli musisz płakać, musisz to zrobić właściwie. – kastermester