Идентификация объектов
Во время выполнения объекты получают уникальные идентификаторы. Две переменные, которые ссылаются на один объект, в действительности ссылаются на один экземпляр этого объекта. По этой причине изменения, произведенные посредством одной переменной, немедленно отображаются через вторую.
Строки в таблице реляционной базы данных не имеют уникальных идентификаторов. Поэтому каждой строке присвоен уникальный первичный ключ, который не совпадает с ключами других строк. Однако этот факт применим только к содержимому таблицы базы данных.
В действительности данные зачастую извлекаются из базы данных и отправляются на другой уровень, на котором с ними работает приложение. Это модель, которую поддерживает LINQ to SQL. Когда данные извлекаются из базы данных в виде строк, пользователь не может сделать никаких предположений относительного того, что две строки, представляющие идентичные данные, в действительности соответствуют одному экземпляру строки. Если дважды выполнить запрос на получение одного определенного клиента, будут извлечены две строки данных. Каждая строка содержит идентичные сведения.
В случае объектов процесс осуществляется совершенно иначе. Можно ожидать, что, несколько раз отправляя классу DataContext запрос на получений одной и той же информации, в действительности будет получен один и тот же экземпляр объекта. Это поведение реализуется по той причине, что объекты имеют особое значение для приложения и полученные данные ведут себя как объекты. Объекты создаются как иерархии или графы. Пользователь может быть уверен, что объекты будут извлечены именно в этом качестве. Он не получит множество реплицированных экземпляров только потому, что отправил несколько запросов на одни и те же сведения.
В LINQ to SQL DataContext управляет удостоверением объекта. При получении новой строки из базы данных строка регистрируется в таблице идентификаций по своему первичному ключу и создается новый объект. При извлечении той же строки приложение отправляется исходный экземпляр объекта. Таким образом, класс DataContext преобразует понятие идентификации в контексте базы данных (то есть первичные ключи) в понятие идентификации в контексте языка программирования (то есть экземпляры). Объект представляется приложению только в состоянии, в котором он находился при первом получении. Если новые данные оказываются другими, они удаляются. Дополнительные сведения см. в разделе "Извлечение объектов из кэша удостоверений".
LINQ to SQL использует этот подход для управления целостностью локальных объектов для поддержки оптимистических обновлений. Поскольку все изменения, происходящие после первого создания объекта, выполняются приложением, действия приложения строго определены. Если во время работы приложения изменения производятся из-за пределов его области действия, эти изменения определяются в момент вызова метода SubmitChanges()
.
Примечание.
Если запрашиваемый объект легко определить как уже извлеченный, то запрос не выполняется. Таблица идентификаций действует как кэш всех ранее извлеченных объектов.
Примеры
Пример кэширования объекта 1
В данном примере, если дважды выполнить один и тот же запрос, каждый раз будет получена ссылка на один и тот же объект в памяти.
Customer cust1 =
(from cust in db.Customers
where cust.CustomerID == "BONAP"
select cust).First();
Customer cust2 =
(from cust in db.Customers
where cust.CustomerID == "BONAP"
select cust).First();
Dim cust1 As Customer = _
(From cust In db.Customers _
Where cust.CustomerID = "BONAP" _
Select cust).First()
Dim cust2 As Customer = _
(From cust In db.Customers _
Where cust.CustomerID = "BONAP" _
Select cust).First()
Пример кэширования объекта 2
В данном примере, если дважды выполнить разные запросы, которые возвращают одну и ту же строку базы данных, каждый раз будет получена ссылка на один и тот же объект в памяти.
Customer cust1 =
(from cust in db.Customers
where cust.CustomerID == "BONAP"
select cust).First();
Customer cust2 =
(from ord in db.Orders
where ord.Customer.CustomerID == "BONAP"
select ord).First().Customer;
Dim cust1 As Customer = _
(From cust In db.Customers _
Where cust.CustomerID = "BONAP" _
Select cust).First()
Dim cust2 As Customer = _
(From ord In db.Orders _
Where ord.Customer.CustomerID = "BONAP" _
Select ord).First().Customer