Представление базы данных
75LINQ --- LINQ to DataSet и SQL --- Представление базы данных
»» В ДАННОЙ СТАТЬЕ ИСПОЛЬЗУЕТСЯ ИСХОДНЫЙ КОД ДЛЯ ПРИМЕРОВ
При генерации сущностных классов для базы данных Northwind указывалась опция /views, чтобы получить сущностные классы, отображаемые на представления базы данных, но пока ничего не говорилось о том, как выполнять запросы к ним. Инструменты генерации сущностных классов — SQLMetal и Object Relational Designer — генерируют свойство Table<Т> в классе [Your]DataContext для каждого представления базы данных и создают соответствующий класс Т. Они опрашиваются подобно таблицам. В общем случае они ведут себя подобно таблицам, отличаясь лишь тем, что доступны только для чтения.
Поскольку сущностные классы, сгенерированные для представлений, не содержат свойств сущностных классов, отображаемых на первичные ключи, они доступны только для чтения. Если вспомнить, что без первичных ключей DataContext не имеет эффективной возможности обеспечить отслеживание идентичности, это очевидно имеет смысл.
Например, база данных Northwind включает представление, которое называется Category Sales for 1997. В связи с этим инструмент SQLMetal сгенерировал общедостуное (public) свойство по имени CategorySalesFor1997s:
public System.Data.Linq.Table<CategorySalesFor1997> CategorySalesFor1997s
{
get
{
return this.GetTable<CategorySalesFor1997>();
}
}
Инструмент SQLMetal также сгенерировал сущностный класс CategorySalesForl997. В следующем примере показано, как опрашивается представление базы данных:
// Используйте свое подключение
Northwind db = new Northwind(@"Data Source=MICROSOF-1EA29E\SQLEXPRESS;
Initial Catalog=C:\NORTHWIND.MDF;
Integrated Security=True");
IQueryable<CategorySalesFor1997> seq = from c in db.CategorySalesFor1997s
where c.CategorySales > (decimal)100000.00
orderby c.CategorySales descending
select c;
foreach (CategorySalesFor1997 c in seq)
{
Console.WriteLine("{0} : ${1}", c.CategoryName, c.CategorySales);
}
Обратите внимание, что в этом коде представление запрашивается точно так же, как таблица. Посмотрим на результат:
Как уже упоминалось, представления доступны только для чтения. В следующем коде предпринимается попытка вставить запись в представление:
// Используйте свое подключение
Northwind db = new Northwind(@"Data Source=MICROSOF-1EA29E\SQLEXPRESS;
Initial Catalog=C:\NORTHWIND.MDF;
Integrated Security=True");
db.CategorySalesFor1997s.InsertOnSubmit(
new CategorySalesFor1997
{ CategoryName = "Legumes", CategorySales = (decimal)79043.92 });
Обратите внимание, что в этом коде даже не предпринимается попытка вызвать метод SubmitChanges. Причина в том, что код не сможет сделать этого без генерации исключения. Посмотрим на результат:
Unhandled Exception: System.InvalidOperationException:
Can't perform Create, Update or Delete operations on
'Table(CategorySalesFori997)' because it has no primary key.
Необработанное исключение: System.InvalidOperationException:
He удается выполнить операции создания, обновления и удаления
на 'Table(CategorySalesFori997)', потому что она не имеет первичного ключа
...
Здесь следует сделать одно предупреждение. Хотя методы InsertOnSubmit и DeleteOnSubmit сгенерируют исключение при вызове Таble<Т>, отображенной на представление базы данных, ничто не помешает внести изменения в свойство сущностного объекта. Можно изменить значение свойства и даже вызвать метод SubmitChanges без генерации исключений, но изменение в свойстве сущностного объекта не будет сохранено в базе данных.