• Microsoft .NET
  • LINQ
  • Оптимизация запросов LINQ при помощи DataLoadOptions

Часто задаваемые вопросы о LINQ - часть вторая

ОГЛАВЛЕНИЕ

Введение и цель

Эта статья вопросов-ответов посвящена 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;
}
}
}