Программирование >>  Каркас сущностей ado.net 

1 ... 5 6 7 [ 8 ]


в этой сущности. Если измененный сущностный объект передается службе от клиентского приложения, он может быть вновь присоединен. Но простого присоединения его к объектному контексту может быть недостаточно, потому что это не даст информации о том, что объект был изменен. Вместо этого оригинальный объект должен быть доступен в объектном контексте. Оригинальный объект можно получить из хранилища, используя ключ с методом GetObjectByKey() . Если сущностный объект уже находится внутри объектного контекста, то он используется; в противном случае он заново извлекается из базы данных. Вызов метода ApplyPropertyChanges() принимает модифицированный сущностный объект в объектный контекст, и если в нем есть изменения, они проводятся внутри существующего сущностного объекта в объектном контексте с тем же ключом внутри объектного контекста, а EntityState устанавливается в Modified. Помните, что метод ApplyPropertyChanges() требует наличия объекта в объектном контексте; иначе будет добавлен новый сущностный объект с EntityState, равным Added.

using (Formula1Entities data = new Formula1Entities())

data.ObjectStateManager.ObjectStateManagerChanged +=

ObjectStateManager ObjectStateManagerChanged; ObjectResult<Racer> racers = data.Racers.Where( it.Lastname=Alonso ); Racer fernando = racers.First(); EntityKey key = fernando.EntityKey; data.Detach(fernando);

Теперь гонщик отсоединен и может изменяться независимо от объектного контекста. fernando.Starts++;

Racer originalObject = (Racer)data.GetObjectByKey(key); data.ApplyPropertyChanges(key.EntitySetName, fernando);

Сохранение изменений в сущностях

На основе всей информации об изменениях, с помощью ObjectStateManager все добавленные, удаленные и модифицированные сущностные объекты могут быть записаны в хранилище посредством метода SaveChanges() класса ObjectContext. Чтобы сверить изменения с объектным контекстом, вы можете присвоить метод-обработчик событию SaveChanges класса ObjectContext. Это событие инициируется перед записью данных в хранилище, так что вы можете добавить некоторую логику верификации, чтобы проверить, действительно ли должны быть выполнены изменения. SaveChanges() возвращает количество сущностных объектов, которые были записаны.

Но что случится, если записи в базе данных, представленные сущностными классами, изменятся после чтения записи? Ответ зависит от свойства ConcurrencyMode, которое устанавливается в модели. Для каждого свойства сущностного объекта вы можете установить ConcurrencyMode равным Fixed или None. Значение Fixed означает, что свойство верифицируется во время записи для определения того, не было ли оно изменено между тем. Значение None - принятое по умолчанию - игнорирует любые изменения. Если некоторые свойства конфигурируются в режиме Fixed, и данные изменяются между чтением и записью сущностных объектов, генерируется исключение OptimisticConcurrencyException. Вы можете обработать это исключение, вызвав метод Refresh() для того, чтобы перечитать актуальную информацию из базы данных в объектный контекст. Этот метод принимает два режима обновления, заданные значением перечисления RefreshMode: ClientWins или StoreWins. Значение StoreWins означает, что актуальная информация берется из базы данных и устанавливается в текущие значения сущностных объектов. ClientWins означает,



что информация базы данных устанавливается в исходные значения сущностных объектов, и потому значения базы данных перезаписываются при следующем вызове SaveChanges. Второй параметр метода Refresh() - это либо коллекция сущностных объектов, либо единственный сущностный объект. Вы можете изменять поведение обновления от объекта к объекту.

static void ChangeInformation()

...

int changes = 0;

changes = data.SaveChanges();

catch (OptimisticConcurrencyException ex) {

data.Refresh(RefreshMode.ClientWins, ex.StateEntries); changes = data.SaveChanges();

Console.WriteLine( {0} entities changed , changes);

LINQ to Entities

В нескольких главах нашей книги вы встречались с LINQ для запроса информации из объектов, баз данных и XML. Конечно, LINQ также доступен и для запросов сущностей.

В LINQ to Entities источником для запроса LINQ служит ObjectQuery<T>. Поскольку ObjectQuery<T> реализует интерфейс IQueryable, выбранные расширяющие методы для запроса определены в классе Queryable из пространства имен System.Linq. Расширяющие методы, определенные этим классом, имеют параметр Expression<T>; вот почему компилятор пишет дерево выражений в сборку. Вы можете прочесть больше о деревьях выражений в главе 11. Дерево выражений затем преобразуется из класса ObjectQuery<T> в запрос SQL.

Вы можете использовать простой запрос LINQ, как показано здесь, чтобы вернуть гонщиков, выигравших более 40 гонок:

using (Formula1Entities data = new Formula1Entities())

var racers = from r in data.Racers

where r.Wins > 40

orderby r.Wins descending

select r; foreach (Racer r in racers) {

Console.WriteLine( {0} {1} , r.Firstname, r.Lastname);

Вот результат обращения к базе данных Formula 1:

Michael Schumacher Alain Prost Ayrton Senna

Вы можете также определить запрос LINQ для доступа к отношениям, как было показано ранее. Переменная r ссылается на гонщиков, а переменная rr - на результаты гонок. В конструкции where определен фильтр для извлечения только гонщиков из Швейцарии (Switzerland), которые заняли определенное место на подиуме.



Чтобы получить информацию о местах, занятых на подиуме, результат группируется, и вычисляется соответствующий счетчик. Сортировка выполняется на основе занятых мест.

using (Formula1Entities data = new Formula1Entities())

var query = from r in data.Racers

from rr in r.RaceResults

where rr.Position <= 3 && rr.Position >= 1 &&

r.Country == Switzerland group r by r.Id into g let podium = g.Count() orderby podium descending

select new { Racer = g.FirstOrDefault(), Podiums = podium }; foreach (var r in query)

Console.WriteLine( {0} {1} {2} , r.Racer.Firstname, r.Racer.Lastname,r.Podiums);

Запущенное приложение вернет имена трех гонщиков из Швейцарии:

Clay Regazzoni 28 Jo Siffert 6 Rudi Fischer 2

Резюме

В этой главе вы ознакомились со средствами ADO.NET Entity Framework. В отличие от LINQ to SQL, описанного в главе 27, этот каркас предлагает отображение на основе поставщиков, а значит, другие разработчики баз данных могут реализовывать свои собственные поставщики.

ADO.NET Entity Framework основан на отображении, определенном CSDL, MSL и SSDL - информации XML, описывающей сущности, отображение и схему базы данных. Используя эту технику отображения, вы можете создавать различные типы отношений, чтобы отображать сущностные классы на таблицы базы данных.

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

LINQ to Entities - это лишь одна грань ADO.NET Entity Framework, которая позволяет вам использовать новый синтаксис запросов для обращения к сущностям.



1 ... 5 6 7 [ 8 ]

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика