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