Поделиться через


Удаленное и локальное выполнение

Вы можете выбрать удаленное выполнение запросов (то есть ядро СУБД выполняет запрос к базе данных) или локально (LINQ to SQL выполняет запрос к локальному кэшу).

Удаленное выполнение

Обратите внимание на следующий запрос:

            Northwnd db = new Northwnd(@"northwnd.mdf");
            Customer c = db.Customers.Single(x => x.CustomerID == "19283");
foreach (Order ord in
    c.Orders.Where(o => o.ShippedDate.Value.Year == 1998))
{
    // Do something.
}
    Dim db As New Northwnd("c:\northwnd.mdf")
    Dim c As Customer = _
(From cust In db.Customers _
 Where cust.CustomerID = 19283).First()
    Dim orders = From ord In c.Orders _
                 Where ord.ShippedDate.Value.Year = 1998
    For Each nextOrder In orders
        ' Do something.
    Next

Если база данных содержит тысячи строк заказов, для обработки небольшого подмножества совсем не обязательно извлекать все строки. В LINQ to SQL EntitySet<TEntity> класс реализует IQueryable интерфейс. Этот метод гарантирует удаленное выполнение подобных запросов. Благодаря этому методу пользователь получает два существенных преимущества:

  • Извлекаются только необходимые данные.

  • Запросы, выполняемые ядром базы данных зачастую более эффективны благодаря индексам базы данных.

Локальное выполнение

В других случаях бывает необходимо иметь полный набор связанных записей в локальном кэше. Для этой цели класс EntitySet<TEntity> предоставляет метод Load для явной загрузки всех членов класса EntitySet<TEntity>.

Если класс EntitySet<TEntity> уже загружен, последующие запросы выполняются локально. Этот метод полезен с двух точек зрения.

  • Если полный набор необходимо использовать локально или несколько раз, можно избежать удаленных запросов и связанных с ними задержек.

  • Сущность можно сериализовать как полную сущность.

В следующем фрагменте кода показывается, как добиться локального выполнения.

            Northwnd db = new Northwnd(@"northwnd.mdf");
            Customer c = db.Customers.Single(x => x.CustomerID == "19283");
c.Orders.Load();

foreach (Order ord in
    c.Orders.Where(o => o.ShippedDate.Value.Year == 1998))
{
    // Do something.
}
        }
    Dim db As New Northwnd("c:\northwnd.mdf")
    Dim c As Customer = _
(From cust In db.Customers _
 Where cust.CustomerID = 19283).First
    c.Orders.Load()

    Dim orders = From ord In c.Orders _
                 Where ord.ShippedDate.Value.Year = 1998

    For Each nextOrder In orders
        ' Do something.
    Next

Сравнение

Эти две возможности предоставляют мощное сочетание параметров: удаленное выполнение для больших коллекций и локальное выполнение для малых коллекций или в тех случаях, когда требуется вся коллекция. Удаленное выполнение реализуется с помощью интерфейса IQueryable, а локальное выполнение - посредством хранящейся в памяти коллекции IEnumerable<T>. Сведения о принудительном локальном выполнении (т IEnumerable<T>. е. см. в разделе "Преобразование типа в универсальный IEnumerable".

Запросы к неупорядоченным наборам

Обратите внимание на важное различие между локальной коллекцией, реализующей List<T> и коллекцию, которая предоставляет удаленные запросы, выполняемые для неупорядоченных наборов в реляционной базе данных. Для методов List<T>, например при использовании значений индексов, требуется семантика списка, которая, как правило, не реализуется посредством удаленного запроса к неупорядоченному набору. По этой причине подобные методы неявно загружают класс EntitySet<TEntity>, чтобы получить возможность локального выполнения.

См. также