Идентификация объекта (LINQ to SQL)
Обновлен: November 2007
Во время выполнения объекты получают уникальные идентификаторы. Две переменные, которые ссылаются на один объект, в действительности ссылаются на один экземпляр этого объекта. По этой причине изменения, произведенные посредством одной переменной, немедленно отображаются через вторую.
Строки в таблице реляционной базы данных не имеют уникальных идентификаторов. Поэтому каждой строке присвоен уникальный первичный ключ, который не совпадает с ключами других строк. Однако этот факт применим только к содержимому таблицы базы данных.
В действительности данные зачастую извлекаются из базы данных и отправляются на другой уровень, на котором с ними работает приложение. Именно такая модель поддерживается технологией LINQ to SQL. Когда данные извлекаются из базы данных в виде строк, пользователь не может сделать никаких предположений относительного того, что две строки, представляющие идентичные данные, в действительности соответствуют одному экземпляру строки. Если дважды выполнить запрос на получение одного определенного клиента, будут извлечены две строки данных. Каждая строка содержит идентичные сведения.
В случае объектов процесс осуществляется совершенно иначе. Можно ожидать, что, несколько раз отправляя классу DataContext запрос на получений одной и той же информации, в действительности будет получен один и тот же экземпляр объекта. Это поведение реализуется по той причине, что объекты имеют особое значение для приложения и полученные данные ведут себя как объекты. Объекты создаются как иерархии или графы. Пользователь может быть уверен, что объекты будут извлечены именно в этом качестве. Он не получит множество реплицированных экземпляров только потому, что отправил несколько запросов на одни и те же сведения.
В LINQ to SQL идентификациями объектов управляет класс DataContext. При получении новой строки из базы данных строка регистрируется в таблице идентификаций по своему первичному ключу и создается новый объект. При извлечении той же строки приложение отправляется исходный экземпляр объекта. Таким образом, класс DataContext преобразует понятие идентификации в контексте базы данных (то есть первичные ключи) в понятие идентификации в контексте языка программирования (то есть экземпляры). Приложение получает объект в том состоянии, в котором он был извлечен в первый раз. Если новые данные оказываются отличными, они удаляются.
LINQ to SQL использует этот подход, чтобы обеспечивать целостность локальных объектов в целях поддержки обновлений оптимистического параллелизма. Поскольку все изменения, происходящие после первого создания объекта, выполняются приложением, действия приложения строго определены. Если во время работы приложения изменения производятся из-за пределов его области действия, эти изменения определяются в момент вызова метода SubmitChanges().
Примечание. |
---|
Если запрашиваемый объект легко определить как уже извлеченный, то запрос не выполняется. Таблица идентификаций действует как кэш всех ранее извлеченных объектов. |
Примеры
Пример кэширования объекта 1
В данном примере, если дважды выполнить один и тот же запрос, каждый раз будет получена ссылка на один и тот же объект в памяти.
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()
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();
Пример кэширования объекта 2
В данном примере, если дважды выполнить разные запросы, которые возвращают одну и ту же строку базы данных, каждый раз будет получена ссылка на один и тот же объект в памяти.
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
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;