Класс ObjectContext
28LINQ --- LINQ to Entities --- Класс ObjectContext
»» В ДАННОЙ СТАТЬЕ ИСПОЛЬЗУЕТСЯ ИСХОДНЫЙ КОД ДЛЯ ПРИМЕРОВ
Класс ObjectContext лежит в основе платформы Entity Framework и LINQ to Entities. Когда создается сущностная модель данных, то создается класс, производный от ObjectContext, со свойствами, представляющими сущностные типы и коллекции, специфичные для базы данных.
В сущностной модели данных Northwind, такой производный класс назывался NorthwindEntities. Этот класс использовался во всех примерах LINQ to Entities для обработки соединения с базой данных, загрузки сущностных объектов и сохранения изменений после выполнения модификаций. И, поскольку он производный, класс NorthwindEntities имеет общедоступные члены — коллекции сущностных объектов, представляющих содержимое базы данных Northwind.
Класс ObjectContext определен в пространстве имен System.Data.Objects.
Прежде чем можно будет использовать какие-либо средства Entity Framework или LINQ to Entities, описанные в предыдущих статьях, потребуется создать новый экземпляр производного класса ObjectContext. Созданный экземпляр отвечает за управление соединением с базой данных и используется для загрузки и сохранения данных в базе.
Существуют два прототипа конструктора ObjectContext, которые описаны ниже:
- Первый унаследованный от ObjectContext конструктор
-
public NortwindEntities();
Это конструктор по умолчанию, создающий новый экземпляр производного класса ObjectContext с использованием строки подключения к базе данных, которая была добавлена в файл App.Config при создании сущностной модели данных. Это прототип применялся во всех примерах посвященных LINQ to Entities.
- Второй унаследованный от ObjectContext конструктор
-
public NortwindEntities{string connectionString);
Этот прототип конструктора позволяет указать детали, которые будут использованы для подключения к базе данных, либо имя строки подключения из файла App.config.
В следующем коде показано использование обоих прототипов:
// Первый прототип
NorthwindEntities context = new NorthwindEntities();
IQueryable<Customer> custs = context.Customers
.Where(c => c.City == "London")
.Select(c => c);
// Второй прототип, на основе класса SqlConnectionStringBuilder
System.Data.SqlClient.SqlConnectionStringBuilder scsb =
new System.Data.SqlClient.SqlConnectionStringBuilder();
scsb.DataSource = @"MICROSOF-1EA29E\SQLEXPRESS;";
scsb.InitialCatalog = "Northwind";
scsb.IntegratedSecurity = true;
scsb.MultipleActiveResultSets = true;
context = new NorthwindEntities(scsb.ToString());
ObjectContext.DatabaseExists()
Метод DatabaseExists возвращает true, если база данных, которая указана в строке подключения, использованной для создания ObjectContext, существует и false — в противном случае.
Метод DatabaseExists имеет один прототип, описанный ниже:
public bool DatabaseExists();
В следующем примере создается экземпляр производного от ObjectContext класса для базы данных Northwind и используется метод DatabaseExists:
NorthwindEntities context = new NorthwindEntities();
bool databaseExists = context.DatabaseExists();
Console.WriteLine("\n База данных {0}", databaseExists ? "существует" : "не существует");

ObjectContext.CreateDatabase()
Метод CreateDatabase использует сущностную модель данных для создания новой базы данных, хотя, конечно, в ней не будет никаких данных. Этот метод обычно применяется в сочетании с методом DatabaseExists.
Метод CreateDatabase имеет один прототип:
public void CreateDatabase();
В следующем примере создается новая база данных с использованием сущностной модели базы данных Northwind:
NorthwindEntities context = new NorthwindEntities();
if (!context.DatabaseExists())
context.CreateDatabase();
ObjectContext.DeleteDatabase()
Метод DeleteDatabase удаляет базу данных, которая указана в строке соединения, использованной для создания производного от ObjectContext экземпляра. Этот метод обычно применяется в сочетании с методом DatabaseExists.
Метод DeleteDatabase имеет один прототип:
public void DeleteDatabase();
В следующем примере метод DeleteDatabase используется для удаления базы данных Northwind. После компиляции и запуска этого примера понадобится восстановить исходную версию базы данных Northwind:
NorthwindEntities context = new NorthwindEntities();
if (context.DatabaseExists())
context.DeleteDatabase();
ObjectContext.SaveChanges()
Метод SaveChanges сохраняет модификации, проведенные в сущностных объектах базы данных. Этот метод генерирует исключение OptomisticConcurencyException если включена проверка параллельного доступа и возникает конфликт обновления.
Метод SaveChanges имеет один прототип, описанный ниже:
public int SaveChanges();
Возвращаемое значение указывает количество добавленных, обновленных или удаленных объектов. В следующем коде модифицируется поле ContactName сущностного типа Customer и вызывается метод SaveChanges() для сохранения модификаций в базе данных:
NorthwindEntities context = new NorthwindEntities();
Customer cust = (from c in context.Customers
where c.CustomerID == "LAZYK"
select c).First();
cust.ContactName = "John Doe";
int modificationCount = context.SaveChanges();
Console.WriteLine("\n Количество проведенных модификаций: {0}", modificationCount);

ObjectContext.AddObject()
Метод AddObject добавляет новый сущностный объект к одной из коллекций, поддерживаемой классом-наследником ObjectContext.
У метода AddObject один прототип:
public void AddObject(string entitySetName, Object entity);
Первый аргумент — имя коллекции, в которую объект должен быть добавлен. Второй аргумент — сущностный объект, который вы хотите добавить. Заметьте, что база данных не обновляется данными, содержащимися в новом сущностном объекте, пока не будет вызван метод SaveChanges.
В следующем примере, показанном ниже, создается новый экземпляр сущностного типа Customer, а также устанавливаются значения полей. Метод AddObject используется для добавления сущностного объекта в коллекцию Customers. Наконец, метод SaveChanges применяется для записи новой записи Customer в базу данных:
NorthwindEntities context = new NorthwindEntities();
// Создать новый объект Customer
Customer cust = Customer.CreateCustomer("LAWN", "Lawn Wranglers");
// Заполнить поля, допускающие null
cust.ContactName = "Mr. Abe Henry";
cust.ContactTitle = "Owner";
cust.Address = "1017 Maple Leaf Way";
cust.City = "Ft. Worth";
cust.Region = "TX";
cust.PostalCode = "76104";
cust.Country = "USA";
cust.Phone = "(800) MOW-LAWN";
cust.Fax = "(800) MOW-LAWO";
context.AddObject("Customers", cust);
context.SaveChanges();
ObjectContext.CreateObject()
Метод CreateObject создает новый сущностный объект. Новый объект не содержит данных и должен быть добавлен к одной из коллекций сущностных объектов в ObjectContext. Только после этого метод SaveChanges сохранит объект в базе данных. Если определение схемы базы данных требует, чтобы некоторые поля не содержали null, необходимо обеспечить наполнение сущностного объекта перед вызовом SaveChanges.
Метод CreateObject строго типизирован, в том смысле, что для каждого сущностного типа, поддерживаемого классом-наследником ObjectContext, существует один прототип в следующей форме, где T — сущностный тип, экземпляр которого необходимо создать:
public T CreateObject<T>();
В случае базы данных Northwind это означает, что для сущностного типа Customer есть такой прототип:
public Customer CreateObject<Customer>();
Для сущностного типа Order прототип выглядит следующим образом:
public Order CreateObject<Order>();
Прототипы для каждого из сущностных типов, содержащихся в сущностной модели данных, похожи на показанные выше.
В коде, приведенном ниже, метод CreateObject используется для создания нового сущностного объекта Customer. Поля заполняются (включая поля CustomerID и CompanyName, которые не допускают null), и объект добавляется в коллекцию Customers с помощью метода AddObject. Новый Customer сохраняется в базе данных вызовом метода SaveChanges:
NorthwindEntities context = new NorthwindEntities();
// Создать новый объект Customer
Customer cust = context.CreateObject<Customer>();
// Заполнить все поля
cust.CustomerID = "LAWN";
cust.CompanyName = "Lawn Wranglers";
cust.ContactName = "Mr. Abe Henry";
cust.ContactTitle = "Owner";
cust.Address = "1017 Maple Leaf Way";
cust.City = "Ft. Worth";
cust.Region = "TX";
cust.PostalCode = "76104";
cust.Country = "USA";
cust.Phone = "(800) MOW-LAWN";
cust.Fax = "(800) MOW-LAWO";
context.AddObject("Customers", cust);
context.SaveChanges();
ObjectContext.DeleteObject()
Метод DeleteObject удаляет объект из кэша сущностей и удаляет соответствующий данные из базы при вызове метода SaveChanges. При удалении объектов, у которых есть связанные с ними объекты, следует соблюдать осторожность.
Метод DeleteObject имеет один прототип:
public void DeleteObject(Object entity);
Аргумент в этом прототипе — это сущностный объект, который должен быть удален.
Код из следующего примера запрашивает сущностные объекты OrderDetail, имеющие OrderID, равный 10248. Результаты перечисляются в цикле foreach и удаляются с помощью метода DeleteObject. Чтобы сохранить удаление, вызывается метод SaveChanges:
NorthwindEntities context = new NorthwindEntities();
// Получить детали заказа 10248
IQueryable<Order_Detail> ods = (from o in context.Order_Details
where o.OrderID == 10248
select o);
foreach (Order_Detail od in ods) {
context.DeleteObject(od);
}
// Сохранить изменения
context.SaveChanges();