|
Программирование >> Каркас сущностей ado.net
Вот результат выполнения этого запроса: Mario Andretti, wins: 12, starts: 128 Dan Gurney, wins: 4, starts: 87 Phil Hill, wins: 3, starts: 48 Обновления Чтение, поиск и фильтрация данных из хранилища - только одна часть работы, которую обычно требуется выполнить в приложении, которое работает с данными. Запись изменений обратно в хранилище - другая часть, которую вам следует знать. Следующие разделы будут посвящены таким темам: □ отслеживание объектов; □ информация об изменении; □ присоединение и отсоединение сущностей; □ сохранение изменений в сущностях. Отслеживание объектов Чтобы разрешить модификацию и сохранение данных, прочитанных из хранилища, сущности нужно отслеживать после того, как они были загружены. Это также требует, чтобы объектный контекст знал о загруженных из хранилища сущностях. Если несколько запросов обращаются к одним и тем же записям, объектный контекст должен возвращать уже загруженные сущности. ObjectStateManager используется объектным контекстом для отслеживания загруженных в контекст сущностей. Следующий пример демонстрирует, что на самом деле, если выполняются два разных запроса, которые возвращают одну и ту же запись из базы данных, диспетчер состояния знает об этом и не создает новой сущности. Вместо этого возвращается та же, что и в первый раз. Экземпляр ObjectStateManager, ассоциированный с объектным контекстом, может быть доступен через свойство ObjectStateManager. Класс ObjectStateManager определяет событие по имени ObjectStateManagerChanged, которое вызывается каждый раз, когда новый объект добавляется или удаляется из объектного контекста. Здесь событию назначается метод ObjectStateManager ObjectStateManagerChanged для получения информации об изменениях. Два разных запроса используются для возврата сущностного объекта. Первый запрос получает первого гонщика из Австрии по фамилии Lauda. Второй запрос запрашивает гонщиков из Австрии, сортирует их по числу побед и берет первый результат. Фактически это будет один и тот же гонщик. Чтобы убедиться в том, что в обоих случаях возвращается одна и та же сущность, используется метод Object.ReferenceEquals() для проверки того, что объектные ссылки действительно ссылаются на один и тот же экземпляр. static void Tracking() using (Formula1Entities data = new Formula1Entities()) { data.ObjectStateManager.ObjectStateManagerChanged += ObjectStateManager ObjectStateManagerChanged; Racer niki1 = data.Racers.Where( it.Country=Austria && it.Lastname=Lauda ).First(); Racer niki2 = data.Racers.Where( it.Country=Austria ). OrderBy( it.Wins DESC ).First(); if (Object.ReferenceEquals(niki1, niki2)) Console.WriteLine( the same object ); static void ObjectStateManager ObjectStateManagerChanged(object sender, CollectionChangeEventArgs e) Console.WriteLine( Object State change - action: {0} , e.Action); Racer r = e.Element as Racer; if (r != null) Console.WriteLine( Racer {0} , r.Lastname); Запустив это приложение, вы можете видеть, что событие ObjectStateManager Changed объекта ObjectStateManager возникает только однажды, и ссылки nuki1 и niki2 указывают на один и тот же экземпляр: Object state change - action: Add Racer Lauda The same object Информация об изменении Объектный контекст также в курсе изменений в сущностях. Следующий пример добавляет и модифицирует гонщика из объектного контекста и получает информацию об изменении. Сначала новый гонщик добавляется методом AddToRacers() класса Formula1Entities. Этот сгенерированный дизайнером метод вызывает метод AddObject() базового класса ObjectContext. Этот метод добавляет новую сущность с информацией EntityState.Added. Затем запрашивается гонщик по имени Alonso. В этом сущностном классе свойство Starts увеличивается, и потому сущность помечается информацией EntityState.Modified. За кулисами же ObjectStateManager информируется об изменении состояния объекта на основе реализации интерфейса INotifyPropertyChanged. Этот интерфейс реализован в базовом сущностном классе StructuralObject. Объект ObjectStateManager присоединен к событию PropertyChanged, и это событие инициируется с каждым изменением сущности. Чтобы получить все добавленные или модифицированные сущностные объекты, вы можете вызвать метод GetObjectStateEntries() класса ObjectStateManager и передать значение перечисления EntityState, как это сделано здесь. Этот метод возвращает коллекцию объектов ObjectStateEntry, хранящую информацию о сущностях. Вспомогательный метод DisplayState выполняет итерацию по этой коллекции для получения детальной информации. Вы можете также получить информацию состояния об отдельной сущности, передав EntityKey методу GetObjectStateEntry(). Свойство EntityKey доступно в сущностных объектах, реализующих интерфейс IEntityWithKey, а именно так обстоят дела с базовым классом EntityObject. Возвращенный объект ObjectStateEntry предоставляет метод GetModifiedProperties() , где вы можете прочесть все значения свойств, которые были изменены, а также получить доступ к исходной и текущей информации о свойствах посредством индексаторов OriginalValues и CurrentValues. static void ChangeInformation() using (Formula1Entities data = new Formula1Entities()) Racer sebastien = new Racer() Firstname = Sebastien , Lastname = Bourdais , Country = France , Starts = 0 data.AddToRacers(sebastien); Racer fernando = data.Racers.Where( it.Lastname=Alonso ).First(); fernando.Starts++; DisplayState(EntityState.Added.ToString(), data.ObjectStateManager.GetObjectStateEntries( EntityState.Added)); DisplayState(EntityState.Modified.ToString(), data.ObjectStateManager.GetObjectStateEntries( EntityState.Modified)); ObjectStateEntry stateOfFernando = data.ObjectStateManager.GetObjectStateEntry(fernando.EntityKey); Console.WriteLine( state of Fernando: {0} , stateOfFernando.State.ToString()); foreach (string modifiedProp in stateOfFernando.GetModifiedProperties()) { Console.WriteLine( modified: {0} , modifiedProp); Console.WriteLine( original: {0} , stateOfFernando.OriginalValues[modifiedProp]); Console.WriteLine( current: {0} , stateOfFernando.CurrentValues[modifiedProp]); static void DisplayState(string state, IEnumerable<ObjectStateEntry> entries) foreach (var entry in entries) { Racer r = entry.Entity as Racer; if (r != null) Console.WriteLine( {0}: {1} , state, r.Lastname); При запуске приложения отображаются добавленные и модифицированные гонщики, а также измененные свойства вместе с их исходными и текущими значениями: Added: Bourdais Modified: Alonso state of Fernando: Modified modified: Starts original: 95 current: 96 Присоединение и отсоединение сущностей Возвращая данные сущности вызывающему коду, может быть важно отсоединить объекты от объектного контекста. Это может понадобиться, например, если сущностный объект возвращается Web-службой. Здесь, если сущностный объект изменяется на клиенте, объектный контекст не знает об изменении. В коде примера метод Detach() объекта ObjectContext отсоединяет сущность по имени fernando и потому объектный контекст не знает об изменениях, выполненных
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |