Часто задаваемые вопросы о LINQ - часть вторая
ОГЛАВЛЕНИЕ
- Скачать исходный код один-ко-многим и многие-к-одному - 1.02 MB
- Скачать LINQ-код оптимизированный при помощи DataLoadOption - 14.8 KB
- Скачать исходный код CRUD LINQ - 2.14 MB
- Скачать код хранимой процедуры - 1.06 MB
Введение и цель
Эта статья вопросов-ответов посвящена LINQ для SQL. Показан простой пример LINQ для SQL, как определить отношение 1-1 и 1-много с помощью LINQ, как можно оптимизировать запросы LINQ, выполнение хранимых процедур с помощью LINQ и простой пример создания, чтения, обновления, удаления (CRUD) с помощью LINQ для SQL.
Простой пример LINQ для SQL
Начнем с простого примера LINQ для SQL, а затем узнаем, как устанавливается отношение в сущностях LINQ.
Шаг 1: Определяются классы-сущности с помощью LINQ
При разработке проекта с помощью многоуровневого подхода, например, 3-уровневого или N-уровневого, приходится создавать бизнес-классы и объекты. Например, ниже показан простой класс, определяющий класс, сопоставленный с таблицей стран, как показано ниже. Свойства класса взаимно-однозначно сопоставлены с таблицей. Такие типы классов именуются классы-сущности.
В LINQ необходимо сначала определить эти классы-сущности с помощью сопоставлений атрибутов. Надо импортировать пространство имен “System.Data.Linq.Mapping;”, чтобы получить атрибуты для сопоставления. Ниже приведен фрагмент кода, показывающий, как атрибут ‘Таблица’ сопоставляет класс с таблицей базы данных по имени ‘Клиент’, и как атрибут ‘Столбец’ сопоставляет свойства со столбцами таблицы.
[Table(Name = "Customer")]
public class clsCustomerEntityWithProperties
{
private int _CustomerId;
private string _CustomerCode;
private string _CustomerName;
[Column(DbType = "nvarchar(50)")]
public string CustomerCode
{
set
{
_CustomerCode = value;
}
get
{
return _CustomerCode;
}
}
[Column(DbType = "nvarchar(50)")]
public string CustomerName
{
set
{
_CustomerName = value;
}
get
{
return _CustomerName;
}
}
[Column(DbType = "int", IsPrimaryKey = true)]
public int CustomerId
{
set
{
_CustomerId = value;
}
get
{
return _CustomerId;
}
}
}
Ниже дано более сложное наглядное изображение сопоставления классов-сущностей со структурой таблицы клиент.
Шаг 2: Используется datacontext для связывания данных таблицы с объектами-сущностями.
Второй шаг – использовать объект контекста данных LINQ для заполнения объектов-сущностей. Datacontext служит посредником между объектами базы данных и классами, сопоставленными с сущностями LINQ.
Создается объект datacontext и создается активное подключение с помощью строки подключения SQL.
DataContext objContext = new DataContext(strConnectionString);
Извлекается коллекция сущностей с помощью типа данных таблица. Это делается с помощью функции ‘gettable’ контекста данных.
Table<clsCustomerEntity> objTable =
objContext.GetTable<clsCustomerEntity>();
После извлечения всех данных в коллекции таблицы пора просмотреть коллекцию таблицы и отобразить запись.
foreach (clsCustomerEntity objCustomer in objTable)
{
Response.Write(objCustomer.CustomerName + "<br>");
}
Вышеприведенный исходный код приложен к статье.
Можно ли инкапсулировать свойства установки и извлечения для сущностей LINQ?
В предыдущем вопросе свойства класса-сущности предоставлялись как открытые свойства, что нарушало основное правило инкапсуляции. Можно определить функции сеттер (установщик) и геттер (извлекатель), инкапсулирующие закрытые свойства.
[Table(Name = "Customer")]
public class clsCustomerEntityWithProperties
{
private int _CustomerId;
private string _CustomerCode;
private string _CustomerName;
[Column(DbType = "nvarchar(50)")]
public string CustomerCode
{
set
{
_CustomerCode = value;
}
get
{
return _CustomerCode;
}
}
[Column(DbType = "nvarchar(50)")]
public string CustomerName
{
set
{
_CustomerName = value;
}
get
{
return _CustomerName;
}
}
[Column(DbType = "int", IsPrimaryKey = true)]
public int CustomerId
{
set
{
_CustomerId = value;
}
get
{
return _CustomerId;
}
}
}