Sobes.tech
Middle

Τι είναι το IQueryable στο πλαίσιο του C#;

sobes.tech AI

Απάντηση από AI

Το IQueryable<T> αποτελεί ένα interface στο LINQ που επιτρέπει τη δημιουργία και εκτέλεση ερωτημάτων σε πηγές δεδομένων που υποστηρίζουν την αργή αξιολόγηση και τη δυνατότητα κατασκευής δένδρου εκφράσεων.

Βασικά χαρακτηριστικά:

  • Αργή αξιολόγηση: Το ερώτημα δεν εκτελείται άμεσα κατά τη δημιουργία, αλλά μόνο όταν χρειάζεται η λήψη αποτελεσμάτων (π.χ., κατά την επανάληψη στη συλλογή ή την κλήση ToList(), ToArray()).
  • Δέντρο εκφράσεων: Το ερώτημα παρουσιάζεται ως δέντρο εκφράσεων (Expression<Func<T>>), το οποίο μπορεί να αναλυθεί και να μετατραπεί σε κάτι κατανοητό από την πηγή δεδομένων (π.χ., ερώτημα SQL για βάση δεδομένων).
  • Φιλτράρισμα και προβολή στην πλευρά της πηγής δεδομένων: Χάρη στο δέντρο εκφράσεων, οι λειτουργίες φιλτραρίσματος (Where), ταξινόμησης (OrderBy) και προβολής (Select) μπορούν να εκτελεστούν στην πλευρά της πηγής δεδομένων, αυξάνοντας σημαντικά την απόδοση, ειδικά με μεγάλα δεδομένα.

Διαφορές από το IEnumerable<T>:

Χαρακτηριστικό IEnumerable<T> IQueryable<T>
Αξιολόγηση Άμεση/Αναβολή (εξαρτάται από την πηγή) Αργή
Ανάκτηση δεδομένων Ολόκληρη η συλλογή μπορεί να φορτωθεί στη μνήμη Φορτώνονται μόνο τα απαραίτητα δεδομένα μετά την εκτέλεση
Πού γίνεται η φιλτράρισμα/προβολή Στη μνήμη της εφαρμογής Στην πλευρά της πηγής δεδομένων
Βάση Συλλογές στη μνήμη, πίνακες Πηγές δεδομένων (βάσεις δεδομένων, web services κ.ά.)
Υποστήριξη εκφράσεων Όχι (χρησιμοποιεί delegates Func<T>) Ναι (χρησιμοποιεί δέντρα εκφράσεων Expression<Func<T>>)

Παράδειγμα χρήσης:

using System.Linq;
using System.Collections.Generic;

// Υποθέτουμε ότι αυτή είναι μια πηγή δεδομένων που υποστηρίζει IQueryable
public class DataSource
{
    private List<Person> people = new List<Person>
    {
        new Person { Name = "Alice", Age = 30 },
        new Person { Name = "Bob", Age = 25 },
        new Person { Name = "Charlie", Age = 35 }
    };

    public IQueryable<Person> GetPeople()
    {
        // Στην πραγματικότητα, αυτό θα ήταν μια κλήση σε βάση δεδομένων ή άλλη πηγή
        return people.AsQueryable();
    }
}

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// Χρήση
public class Program
{
    public static void Main(string[] args)
    {
        DataSource dataSource = new DataSource();

        // Δημιουργία ερωτήματος με IQueryable - το ερώτημα δεν έχει εκτελεστεί ακόμα
        IQueryable<Person> query = dataSource.GetPeople()
            .Where(p => p.Age > 28)
            .OrderBy(p => p.Name);

        // Εκτέλεση του ερωτήματος κατά την επανάληψη
        foreach (var person in query)
        {
            Console.WriteLine($"{person.Name}, {person.Age}");
        }

        // Εκτέλεση του ερωτήματος κατά τη μετατροπή σε λίστα
        List<Person> seniors = query.ToList();
    }
}