ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    Введення в ObjectSpaces
         

     

    Інформатика, програмування

    Введення в ObjectSpaces

    Тимофій Казаков (TK)

    зберігаються об'єкти

    В. NET Framework управління даними здійснюється на рівні об'єктів. Кожен об'єкт характеризується своїм станом (властивості), поведінкою (методи), і є екземпляром якого-небудь конкретного класу. У рамках програми класи можуть відрізнятися за цільовим призначенням - це можуть бути елементи управління, що відображають інтерфейс користувача, або сервісні класи, що відповідають за зв'язки з базами даних і роботу з мережевими функціями, це можуть бути класи "повідомлень", що забезпечують обмін інформацією між частинами додатки. Всі ці сутності об'єднує одна спільна риса - час їхнього життя звичайно не перевищує часу життя всього програми. Але, крім перерахованих вище категорій класів, можна виділити цілий ряд сутностей, час життя яких перевищує термін життя програми. Наприклад, в бізнес-завданнях роль подібних сутностей можуть грати об'єкти "Клієнт", "Замовник", "Продукт". Таким об'єктам необхідно надати можливість збереження свого стану в зовнішнє сховище.

    В. NET Framework існують готові засоби для роботи з зберігаються об'єктами, - є можливість зберігати стан об'єктів в двійковому вигляді з використанням BinaryFormatter або XML-форматі використанням XmlSerializer. Всі ці кошти надають можливості збереження "графів" об'єктів, однак зберігається інформація не оптимізована для виконання запитів до що зберігається даними - так, пошук необхідної інформації в XML-файлі, що містить кілька тисяч записів, може виявитися неприйнятно повільним. У більшості подібних випадків у якості сховища інформації підійде реляційна СУБД - дані зберігаються в таблицях, для додаткового контролю цілісності між ними встановлюються відносини, пошук інформації здійснюється з використанням мови запитів SQL. Аналогічну функціональність надають спеціальні бібліотеки Object/Relational Mapping (O/R Mapping). Така бібліотека перекладає на себе всю "чорну" роботу по збереження/завантаження інформації з об'єктної моделі додатки в реляційну модель бази даних. В. NET Framework 1.2 для цих цілей є спеціальний набір класів з простору імен System.ObjectSpaces .*.

    ObjectSpaces

    Якщо раніше, використовуючи ADO.NET, потрібно було самостійно писати SQL-запити, то тепер ця вимога стає необов'язковим - ObjectSpaces беруть на себе всю турботу про відображення класів програми на різні джерела даних. При цьому ми можемо створювати нові об'єкти, зберігати їх, виконувати різні запити - всі необхідні дії по взаємодії з джерелом даних будуть виконуватися всередині ObjectSpaces (при цьому дані можуть знаходитися як в традиційній БД, так і бути представленими в XML формі)        

    ПОПЕРЕДЖЕННЯ   

    Поточна версія ObjectSpaces   підтримує в якості джерела даних тільки SQL Server 7.0 і вище.     

    Для об'єктів програми ObjectSpaces надає наступні можливості:

    Прозоре відображення примірників. NET об'єктів на джерело даних.

    Підтримку ієрархій класів для збережених об'єктів.

    Збереження взаємозв'язків між об'єктами (один до одному, один до багатьох, багато до багатьох).

    відкладену завантаження пов'язаних об'єктів. Побудова запитів з використанням OPath.

    Архітектура ObjectSpaces

    Яка функціональність потрібно від O/R Mapping-бібліотеки? Крім очевидних завдань - завантаження/збереження стану об'єкта та виконання операцій пошуку, є й менш очевидні завдання -- відстеження стану та ідентифікація об'єкта. Для чого це потрібно?

    Відстеження стану потрібно для ухвалення рішення про необхідність збереження об'єкта. Цілком очевидно, що якщо жодне з полів об'єкта не змінювалося, то повторно зберігати ту саму інформацію абсолютно не обов'язково. Інформація про оригінальні значеннях полів може знадобитися і для досягнення "оптимістичній паралельності" (optimistic concurrency) в ситуаціях, коли в БД немає колонки з версією запису. Також можна оптимізувати збереження полів об'єкта для ситуацій, коли один об'єкт відображається на декілька таблиць у базі даних, просто не оновлюючи не змінилися дані.        

    ПРИМІТКА   

    Optimistic concurrency (оптимістичний   паралелізм) - це можливість двом незалежним клієнтам редагувати одну й   ту ж інформацію без додаткового блокування будь-яких ресурсів. Всі   перевірки щодо правомочності зроблених змін здійснюються тільки   в момент збереження запису. Це можна реалізувати, наприклад, додаванням в   таблицю спеціального поля для ідентифікації версії запису (наприклад, timestamp).     

    В яких випадках потрібно вміти ідентифікувати об'єкт? У випадку з O/R Mapping-бібліотекою ми працюємо не з "сирими" даними, а з реальними об'єктами. Це означає, що одному значенню первинного ключа в базі даних повинен відповідати один об'єкт у додатку. Справді, розумно розраховувати, що всі можливі способи одержання одного і того ж об'єкта з бази даних кожного разу повинні повертати одну й ту ж посилання. Це означає, що O/R Mapping-бібліотека повинна відстежувати всі файли об'єкти, і в разі повторної спроби відновити об'єкт з тим же значенням первинного ключа повертати посилання на вже завантажений.

    Які є шляхи для реалізації подібної функціональності? Реалізація функціональності ідентифікації об'єктів перетинається з реалізацією відстеження стану об'єкта і не уявляє особливої складності. Тому зосередимося на тому, якими способами можна забезпечити відстеження стану.

    Є два варіанти відстеження стану об'єкта. У першому варіанті ініціатором збереження стану виступає сам об'єкт. За другого варіанту об'єкт грає пасивну роль, а вся необхідна функціональність реалізується в бібліотеці O/R Mapper. Розглянемо кожну з двох реалізацій більш докладно.

    Ініціатором збереження виступає об'єкт. У даній ситуації O/R Mapper надає механізм зберігання оригінальних і поточних значень, а "зберігається" об'єкт виступає лише інтерфейсом для роботи c цим сховищем. Тут можна виділити два можливих напрямки:

    "зберігається" клас описується на деякому метамови. Що це за метамова, і які засоби роботи з ним використовуються, в загальному випадку не так важливо. Відмітною особливістю даної реалізації є те, що весь необхідний код відстеження стану генерується на етапі розробки (компіляції). Як приклад такого підходу можна взяти реалізацію Borland Enterprise Core Objects (ECO).

    Всі властивості, для яких необхідно надати можливості "збереження" оголошуються як абстрактні, сам такий клас також стає абстрактним (MustInherit в VisualBasic). На O/R Mapping-бібліотеку в такій ситуації лягає відповідальність за створення спадкоємця "зберігається" (наприклад, через Reflection.Emit) класу з неминучою реалізацією всіх зберігаються властивостей, і надання фабрики класу для його створення. Знайти реалізацію подібної функціональності можна в ранній preview-версії ObjectSpaces і в EntityBroker ( http://www.thona -consulting.com).

    У кожного з цих напрямів є свої достоїнства і недоліки. Плюсом першого напряму є більш швидкий запуск, тому що весь необхідний код згенерований ще на етапі компіляції. Тим часом, цей плюс може стати і мінусом - якщо з якоїсь причини реалізація "інформацію" стану зміниться, доведеться повторити операцію генерації коду зберігається класу і переконфігурувати його. У разі використання другого напрямку буде досить замінити реалізацію O/R Mapper.

    Об'єкт відіграє пасивну роль, вся реалізація - в O/R Mapper. У цій ситуації до "зберігається" класу не пред'являється ніяких додаткових вимог. Основний плюс даного підходу полягає в тому, що для долучення "зберігання" до існуючого класу його не треба ніяк модифіковані (максимальна прозорість у використанні O/R Mapper), а мінус полягає в тому, що для збереження закритих полів класу доводиться використовувати механізми рефлексії, що може негативно позначитися на продуктивності.

    У ObjectSpaces обраний другий варіант. В основі реалізації ObjectSpaces (Малюнок 1) лежать три основні класи: ObjectEngine, ObjectContext і ObjectSpace.

    ObjectEngine (його використання більш детально розглядається нижче) відповідає за низькорівневе взаємодію з джерелом даних.

    ObjectContext - це реалізація механізмів ідентифікації і відстеження стану "зберігаються" класів.

    ObjectSpace. Клас ObjectSpace на більш високому рівні об'єднує функціональність, закладену в реалізаціях ObjectEngine і ObjectContext. Для відображення реляційної моделі даних в об'єктну ObjectSpace використовує набір XML-схем, описуваних класом MappingSchema.

    Малюнок 1 Архітектура ObjectSpaces.

    Схеми даних

    Для більшості додатків описати однозначне ( "один до одного ") відображення об'єктної моделі даних на реляційну модель не можна, іноді потрібно спеціально описувати те, як об'єкти повинні відображатися на джерело даних. У ObjectSpaces це завдання виконує клас MappingSchema (простір імен System.Data.Mapping). Цей клас призначений для опису:

    RSD (Relational Schema Definition) - схеми, яка описує таблиці, поля і відносини між ними;

    OSD (Object Schema Definition) - схеми, що описує об'єкти;

    MSD (Mapping Schema Definition) - схеми відображення.

    ObjectSpaces дає можливість самостійно формувати стан класу MappingSchema або завантажувати його стан з XML-файлу. Розглянемо використання MappingSchema на основі бази даних Northwind зі складу SQL Server. На першому етапі потрібно описати структуру цієї бази даних у RSD-схемою:        

      

    xmlns: rsd = "http://schemas.microsoft.com/data/2002/09/28/rsd">   

      

      

      

      

      

      IncrementStep = "1" IncrementSeed = "1 "/>   

      

      Precision = "5 "/>   

      

      

      

      

      

       0   

      

      

      

      

      

      

      

      

      

      

      

      

      

      

      

      

      SqlType = "nvarchar" Precision = "30 "/>   

      

    Precision = "24 "/>   

      

      

      

      

      

      

      

      

      

        

    Ця схема описує дві таблиці з бази даних Northwind (малюнок 2). Для таблиць Customers і Orders описуються вихідні поля в БД, первинні ключі, а також зв'язки між таблицями.

    Малюнок 2. ER-діаграма

    Крім цього, знадобиться описати OSD-схему, яка буде описувати об'єкти C #-коду.        

      

    xmlns: osd = "http://schemas.microsoft.com/data/2002/09/20/persistenceschema">   

      

      

      

      

      

      

      

      

      

      

      Hidden = "false" Key = "true"   Alias = "OrderID" />   

      

      

      

      

      

      

      

      

      

      

    Type = "OneToMany"   ParentClass = "Rsdn.Samples.Northwind.Customer"   

      ParentMember = "Orders"   ChildClass = "Rsdn.Samples.Northwind.Order"   

      ChildMember = "Customer" />   

      

        

    Малюнок 3. Об'єктна модель.

    Після оголошення RSD-і OSD-схем (малюнок 3), потрібно створити Mapping-схему, яка визначить відображення однієї схеми на іншу:        

      

      

      

      

      

      

      

      FromVariable = "Customers" ToVariable = "Orders">   

      

      

      

      

      

      

      

      

      

    TargetSelect = "Rsdn.Samples.Northwind.Customer">   

      

      

      

      

      

      

      TargetSelect = "Rsdn.Samples.Northwind.Order">   

      

      

      

      

      

      TargetField = "EmployeeID" NullValue = "-1" />   

      

      

      

      

        

    OPath

    Одне з основних завдань при роботі з інформацією - це створення запитів для вибірки необхідних даних. Так, у випадку РСУБД можна використовувати мову запитів SQL, для вибірки інформації з XML-джерел у нас є XPath. Але як SQL, так і XPath - це мови запитів, які занадто сильно прив'язані до моделі зберігання даних і, як результат, для O/R Mapper доводиться застосовувати спеціальна мова запитів, який дозволить створювати запити до даних в термінах об'єктної моделі програми, але легко транслювати їх у мову, що розуміється сховищем даних (для ObjectSpaces і MS SQL Server це SQL).

    Для звернення до джерела даних в ObjectSpaces використовується спеціальна мова запитів - OPath. Синтаксис цієї мови (віддалено він нагадує XPath) дозволяє виконувати запити до джерела даних, грунтуючись на ієрархії класів, що використовуються в додатку. В даний час OPath підтримує наступний набір операторів (для операторів може використовуватися синтаксис як C #, так і VB.NET):        

    Оператор в C # стилі         

    Оператор в VB стилі         

    Опис             

    .   

    []         

    .   

    ()         

    Оператори угруповання   використовуються для позначення властивостей і угруповання виразів.   Наприклад: Customer [CustomerID = 'alfki']. Orders.ShipDate> # 11/12/2003 #             

    !         

    not         

    Логічне заперечення. not (Customer [CustomerID = 'alfki'])             

    *   

    /   

    %         

    *   

    /   

    MOD         

    Множення, ділення,   отримання модуля             

    +   

    -         

    +   

    -         

    Додавання, віднімання             

    <   

    >   

    <=   

    > =         

    <   

    >   

    <=   

    > =         

    Порівняння двох   значенійCustomer.CreateDate> # 12/09/2002 #             

    =   

    ! =   

    ==         

    =   

    <>   

    ==         

    Рівність двох значень             

    & &   

    | |         

    and   

    or         

    Customer.Region = 'ru' | | Customer.Region = 'en'             

    ^         

    ^         

    Символ ^ використовується для   позначень батьків/нащадок. У випадку використання оператора ^ наступні   два вирази еквівалентні: Orders.OrderDetail [^. OrderDate>   # 1/1/2003 #] Orders. [OrderDate> # 1/1/2003 #]     

    ObjectSpace

    При роботі з зберігаються об'єктами нам потрібні наступні можливості - завантаження збережених об'єктів, відстеження стану і повернення змін назад, до бази даних. Клас ObjectSpace об'єднує в собі всі ці можливості. Розглянемо окремі моменти роботи з цим класом.

    Створення екземпляра ObjectSpace

    Для створення екземпляра ObjectSpace потрібно мати три схеми - RSD, OSD і MSD (при бажанні їх можна скомбінуйтеовать в одному XML-файлі), а також примірник SqlConnection для взаємодії з джерелом даних.        

    // Створення екземпляра класу ObjectSpaces   

    using (SqlConnection conn = new SqlConnection (   

    "Data Source = tim;   Integrated Security = SSPI; Database = northwind "))   

    (   

    ObjectSpace os = new   ObjectSpace ( "map.xml", conn);      

    // Працюємо з os. Явно відкривати підключення SqlConnection НЕ   обов'язково.   

    // Це відбувається автоматично.   

    )     

    Запит до джерела даних

    Після ініціалізації екземпляра ObjectSpace можна звернутися до джерела даних. Для цього у класу ObjectSpace є три методи GetObject, GetObjectReader, GetObjectSet які дозволяють одержувати дані в вигляді трьох різних форм - одиночний об'єкт, курсор або список.        

    // Визначимо "зберігаються" об'єкти, які   будемо використовувати надалі   

    public class Customer   

    (   

    public string CustomerID;   

    public string Name;   

    public string Company;   

    public string Phone;   

    public string Fax;   

    public ArrayList Orders = new   ArrayList ();   

    )      

    public class Order   

    (   

    private int _orderID = 0;      

    public int OrderID   

    (   

    get (return _orderID;)   

    )      

    public DateTime OrderDate;   

    public DateTime RequiredDate;   

    public DateTime ShippedDate;   

    public Decimal Freight;   

    public int EmployeeID;   

    public Customer Customer;   

    )      

    // Витягуємо об'єкт   Customer (включаючи підпорядковане властивість Orders)   

    // на основі OPath-запиту (City = 'Berlin'   & & Orders.OrderDate <# 1998.10.10 #).   

    // Для кожного примірника   класу Customer завантажується властивість "Orders".   

    Customer cust = (Customer) os.GetObject (typeof (Customer),   

    "City = 'Berlin'   & & Orders.OrderDate <# 1998.10.10 # "," Orders ");     

    У що виливається виклик наведеного вище методу os.GetObject? Використовуючи Profiler з MS SQL Server, можна побачити, що в БД буде виконаний наступний SQL-запит (відформатовано для приведення в більш "Читається" вид):        

    exec sp_executesql   

    N'select Customers. [CustomerID],   

    Customers. [CompanyName],   

    Customers. [ContactName],   

    Customers. [City],   

    Customers. [Phone]   

    from   [Northwind]. [Dbo]. [Customers] as Customers   

    where ((Customers. [City]) =   (@ p0))   

    AND (EXISTS (   

    select Orders. [OrderID],   Orders. [CustomerID]   

    from   [Northwind]. [Dbo]. [Orders] as Orders   

    where ((Customers. [CustomerID])   = (Orders. [CustomerID ]))   

    AND   ((Orders. [OrderDate])> (@ p1))))   

    order by 1;      

    select Customers. [CustomerID],   

    Orders. [OrderID],   

    Orders. [CustomerID],   

    Orders. [RequiredDate],   

    Orders. [ShippedDate],   

    Orders. [OrderDate]   

    from   [Northwind]. [Dbo]. [Customers] as Customers,   

    [Northwind]. [dbo]. [Orders]   as Orders   

    where (((Customers. [City]) =   (@ p0))   

    AND (EXISTS (   

    select Orders. [OrderID],   Orders. [CustomerID]   

    from   [Northwind]. [Dbo]. [Orders] as Orders   

    where   ((Customers. [CustomerID]) = (Orders. [CustomerID ]))   

    AND   ((Orders. [OrderDate ])>(p1)) )))   

    AND   ((Customers. [CustomerID]) = (Orders. [CustomerID]))   

    order by 1, 2, 3; ',      

    N '@ p0 nvarchar (6), @ p1 datetime', @ p0 = N'Berlin ',   

    @ p1 = 'Oct 10 1998 12:00:00:000 AM'     

    Створення записів в базі даних

    Одне з великих переваг у використанні ObjectSpaces полягає в тому, що для додавання об'єкту властивостей "зберігання" його не треба спеціальним чином модифіковані (успадковувати від спеціального базового класу, спеціальним чином розмічати властивості або поля). Подібна прозорість реалізації ObjectSpaces дає переваги у використанні.        

    // Робота з об'єктами   Customer і Orders не залежить   

    // від того, використовується   ObjectSpaces чи ні   

    Customer cust = new Customer ();   

    Order ord = new Order ();      

    cust.Id = "ALFQI";   

    cust.Name = "MyName";   

    cust.Company = "MyCompany";   

    cust.Phone = "MyPhone";   

    cust.Fax = "MyFax";      

    ord.Customer = cust;   

    ord.OrderDate = DateTime.Now;   

    ord.ShippedDate = DateTime.Now;   

    ord.RequiredDate = DateTime.Now;   

    cust.Orders.Add (ord);      

    // Перед збереженням   об'єктів необхідно помістити їх в контекст   

    // ObjectSpaces. Прапор   InitialState.Inserted показує, що ми додаємо нову   

    // запис в базу даних   

    os.StartTracking (ord, InitialState.Inserted);   

    os.StartTracking (cust, InitialState.Inserted);      

    // Зберігаємо екземпляр класу Customer.   

    // Параметр   PersistenceOptions (Depth.ObjectGraph) повідомляє,   

    // що буде збережений весь   граф об'єктів.   

    os.PersistChanges (cust, new PersistenceOptions (Depth.ObjectGraph ));     

    Видалення записів з використанням ObjectSpaces

    Існуюча версія ObjectSpaces підтримує видалення об'єктів тільки в тому випадку, якщо вони раніше були додані в контекст ObjectSpaces.        

    ПРИМІТКА   

    Щоб видалити об'єкт з бази даних його   необхідно попередньо додати в контекст ObjectSpaces. Це можна   зробити, використовуючи методи GetObject, GetObjectReader, GetObjectSet класу   ObjectSpace, або додати об'єкт в контекст самостійно за допомогою методу   StartTracking             

    Customer   cust = new Customer ();   

    cust.Id   = "ALFQI";      

    // Перед операцією над об'єктом   необхідно помістити його в контекст   

    // ObjectSpaces. Прапор   InitialState.Unchanged показує, що об'єкт раніше   

    // був збережений у базі даних   

    os.StartTracking (cust,   InitialState.Unchanged);      

    // Позначає екземпляр класу Customer   як видаляється.   

    os.MarkForDeletion (cust);      

    // Зберігаємо зміни в базі даних   

    os.PersistChanges (cust);     

    Відкладена завантаження даних

    Відкладена завантаження даних - це дуже корисна можливість, реалізована в ObjectSpaces. Правда, використання цієї функціональності затьмарюється її недостатньою "прозорістю". Це означає, що в випадку, коли необхідно довантажувати залежні класи на вимогу, доведеться модифіковані вихідний код. На щастя, модифікації незначні.        

    public class Customer   

    (   

    public string CustomerID;   

    public string Name;   

    public string Company;   

    public string Phone;   

    public string Fax;      

    // Для відкладеної завантаження списку замовлень необхідно перейти   

    // від використання ArrayList до   використання спеціального класу з   

    // ObjectSpaces - ObjectList.   

    public ObjectList Orders = new   ObjectList ();   

    )      

    public class Order   

    (   

    private int _orderID = 0;      

    public int OrderID   

    (   

    get (return _orderID;)   

    )      

    public DateTime OrderDate;   

    public DateTime RequiredDate;   

    public DateTime ShippedDate;   

    public Decimal Freight;   

    public int EmployeeID;      

    // Для відкладеної завантаження класу Customer, ми змінюємо тип поля з Customer   

    // на ObjectHolder. Саме ObjectHolder буде відповідати за підвантаження   потрібних   

    // даних.   

    private ObjectHolder _customer   = New ObjectHolder ();      

    public Customer Customer   

    (   

    get (return (Customer)   _customer.InnerObject;)   

    set (_customer.InnerObject = value;)   

    )   

    )     

    Крім зміни коду програми, відкладену завантаження властивостей слід оголосити в OSD-схемі. Для цього потрібно додати опис полів спеціальний атрибут LazyLoad = "true".        

      

      

      

      

      

      

      

      

      

      

    Hidden = "false"   Key = "true" Alias = "OrderID" />   

      

      

      

      

      

      

        

    Після цього можна працювати з відновленим об'єктом як завжди:        

    using (SqlConnection conn = new SqlConnection (   

    "Data Source = tim;   Integrated Security = SSPI; Database = northwind "))   

    (   

    ObjectSpace os = new ObjectSpace ( "map.xml",   conn);      

    Customer cust =   (Customer) os.GetObject (typeof (Customer),   

    "CustomerID = 'alfki'");      

    // Список замовлень завантажиться при першому   зверненні   

    foreach (Order order in cust.Orders)   

    (   

    Console.WriteLine ( "Customer:   (0), OrderDate: (1) ",   

    order.Customer.Name,   order.OrderDate);   

    )   

    )             

    Метод         

    Опис             

    BeginTransaction, Commit,   Rollback         

    Управління транзакціями.   Варто звернути увагу, що метод Rollback НЕ відкочується зміни в   зберігаються об'єктах, тому можуть виникати ситуації, коли інформація в БД і   інформація, що зберігаються в об'єктах виявляться неузгодженості. Тому, по   уникнути конфліктів, рекомендується після Rollback створювати новий екземпляр   ObjectSpaces.             

    GetObject         

    Отримати одиночний об'єкт   заданого типу з бази даних. У параметрах методу можна передати як   OPath-запит, так і список дочірніх об'єктів, які повинні бути завантажені   одночасно з запитуваним об'єктом.             

    GetObjectReader         

    Отримати з бази даних   об'єкти через курсор, використовуючи семантику, аналогічну що використовується при роботі   з IDataReader.             

    GetObjectSet         

    Отримати об'єкти з БД в   вигляді єдиного масиву. На відміну від ArrayList, клас ObjectSet надає   додаткові можливості відстеження оригінальних значень, передачі   змін через Remoting і деякі інші.             

    PersistChanges         

    Зберегти змінений об'єкт   в БД.             

    MarkForDeletion         

    Позначити об'єкт для   видалення. Реальне видалення відбувається при виклику PersistChanges.             

    Resync         

    Синхронізувати состочніе   об'єкта з інформацією з БД.             

    StartTracking         

    "Позначити" об'єкт як зберігається.   Крім поточних значень, у контексті зберігається і стан об'єкта   (новий/змінений/вилучений/без змін)       

    Додаткові можливості ObjectSpaces

    Читання даних з використанням DbObjectReader

    В окремих випадках використання класу ObjectSpace може виявитися надмірним або незручним. Наприклад, якщо для доступу до бази даних необхідно використовувати процедури, що зберігаються, більша частина функціональності ObjectSpaces виявиться непотрібною. Але і для подібних ситуацій у ObjectSpaces є своє рішення. Якщо потрібно витягувати з довільного джерела даних інформацію у вигляді об'єктів додатка, можна використовувати клас DbObjectReader. Виступаючи як тонкий прошарок між ADO.NET-курсором (IDataReader) і класами програми, DbObjectReader дозволяє завантажувати зберігаються об'єкти з джерел даних, які не підтримуються ObjectSpaces напряму.        

    public static void Main ()   

    (   

    DataTable table = new   DataTable ();      

    table.Columns.Add ( "CustomerID",   typeof (int ));   

    table.Columns.Add ( "CompanyName",   typeof (string ));   

    table.Columns.Add ( "ContactName",   typeof (string ));   

    table.Columns.Add ( "Phone",   typeof (string ));   

    table.Rows.Add (new object [] (   1, "MyCompany", "MyCustomer", "222 33 22" });      

    using (IDataReader reader =   table.GetDataReader ())   

    (   

    DbObjectReader objectReader = new   DbObjectReader (reader,   

    typeof (Customer), new   MappingSchema ( "map.xml "));   

    while (objectReader.Read ())   

    (   

    Customer cust =   (Customer) objectReader.Current;   

    Console.WriteLine (cust.Name);   

    )   

    )   

    )     

    ObjectEngine

    Клас ObjectEngine лежить в основі ObjectSpaces і реалізує механізми взаємодії з джерелом даних. У більшості випадків ObjectEngine прямо не використовується, але в ситуаціях, коли необхідно виконати OPath-запит або зберегти об'єкт в БД в обхід основної функціональності ObjectSpaces і з мінімальними витратами - використання ObjectEngine може стати в нагоді.        

    // Невеликий приклад   використання функціональності ObjectEngine   

    public static void Main ()   

    (   

    using (SqlConnection conn = new   SqlConnection (   

    "Data Source = tim;   Integrated Security = SSPI; Database = northwind "))   

    (   

    conn.Open ();      

    // Враховуючи, що ObjectEngine - це   "Низькорівневий" клас, деяку частину   

    // підготовчої роботи доводиться   виконувати самостійно.   

    ObjectContext context =   

    new CommonObjectContext (new   ObjectSchema ( "osd.xml "));   

    MappingSchema msd = new   MappingSchema ( "map.xml ");   

    ObjectSchema osd = new   ObjectSchema ( "osd.xml ");   

    ObjectSources sources = new   ObjectSources ();      

      sources.Add ( "NorthwindRSD", conn);      

    // Створюємо OPath запит і читаємо дані з БД   

    ObjectExpression expr = OPath.Parse (   

    new   ObjectQuery (typeof (Customer), "", ""), osd);      

    // Ще один побічний ефект ObjectEngine - перед використанням OPath   

    // запит треба "компілювати".   

    CompiledQuery query = expr.Compile (msd);   

    Customer cust = null;      

    // Виконуємо OPath-запит, використовуючи   "Об'єктовий" курсор.   

    using (ObjectReader reader =   

      ObjectEngine.GetObjectReader (sources, context, query, new object [] (   }))   

    (   

    while (reader.Read ())   

    (   

    cust =   (Customer) reader.Current;      

    Console.WriteLine (cust.Name);   

    )   

    )      

    // Створити об'єкт і зберігаємо його в   джерелі даних   

    cust = new Customer ();   

    cust.CustomerID =   "alfq";   

    cust.Name =   "MyName";   

    cust.Phone =   "MyPhone";   

    cust.Company = "MyComp";   

    context.Add (cust,   ObjectState.Inserted);      

      ObjectEngine.PersistChanges (msd, sources, context,   

    new object [] (cust),   PersistenceOptions.Default);   

    )   

    )     

    Розширення ObjectSpaces

    Використання декількох XML-схем для опису структури класів програми, реляційної структури БД, а крім того ще й Mapping-схеми, що не може не пригнічувати. Звичайно, у фінальній версії. NET Framework 1.2 можливості візуального проектування цих схем повинні обов'язково з'явитися, але поки їх немає, можна скористатися сторонніми засобами. Одне з таких засобів входить в приклад ObjectSpacesPDCSamples.zip (фото можна знайти на http://www.gotdotnet.com).

    До складу цього прикладу входить спеціальна утиліта для створення всіх необхідних XML-схем (малюнок 4).

    Малюнок 4. Microsoft ObjectSpaces Mapper Utility.

    Крім цього, в даний приклад входить реалізація класу ObjectPersistence. Цей клас володіє однією характерною особливістю - він приховує в собі не тільки створення XML-описів, але і створення необхідної бази даних. Розглянемо найпростіший приклад використання ObjectPersistence.        

    using System;   

    using Microsoft.ObjectSpaces.ObjectPersistence;      

    class ObjectPersistenceDemo   

    (   

    // Вихідний код класу ObjectPersistence також доступний у рамках прикладу   

    static ObjectPersistence op =   new   

    ObjectPersistence ( "Data   Source = local; Integrated Security = true; ",   

    "Persistence ");      

    static void Main (string [] args)   

    (   

    Customer c = new Customer ();      

    // Шукаємо замовника в базі даних   

    c = (Customer) op.LoadObject (typeof (Customer),   "CustomerID = 'alfki'");   

    if (c == null)   

    (   

    c = new   Customer ( "alfki ");   

    c.Comments = "New   Customer ";   

    )   

    else   

    (   

    c.Comments = "Old   Customer ";   

    )   

      

    // Зберігаємо зміни.   

    // Якщо база даних/таблиця ще не створені, то це відбудеться зараз   

    op.Persist (c);   

    )   

    )     

    Клас ObjectPersistence спроектований таким чином, що для його використання не обов'язково попередньо створювати базу даних, настроювати XML-схеми даних - все це робиться всередині реалізації ObjectPersistence. Так, у наведеному вище прикладі на SQL Server буде створена база даних Persistence, і в неї буде додана таблиця з ім'ям Customer. Звичайно, не в кожному проекті можна допустити подібні вольності з боку бібліотеки доступу до даних, але для простих реалізацій - це чудова можливість приховати непотрібні деталі.

    Підсумок

    Технології доступу до даних у. NET Framework 1.2 містять безліч корисних нововведень, але якщо для ADO.NET це швидше еволюційні зміни, пов'язані з простим розширенням бібліотеки, то ObjectSpaces є абсолютно новим продуктом, який може кардинальним чином змінити підхід до роботи з даними. Звичайно, в даний момент робота над бібліотекою ще далека від завершення. До моменту виходу VisualStudio «Whidbey» ми зможемо побачити в ній багато змін, починаючи з використання generics і розширення можливостей OPath, і закінчуючи DML-операторами для видалення об'єктів без попереднього їх вилучення.

    Список літератури

    Для підготовки даної роботи були використані матеріали з сайту http://www.rsdn.ru/

         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status