Creatio development guide
Это документация Creatio версии 7.11.0. Мы рекомендуем использовать новую версию документации.

Работа с локализуемыми данными с помощью Entity

Glossary Item Box

Общие сведения

Начиная с версии 7.9.1, в метод Entity.FetchFromDB() добавлена возможность получения мультиязычных данных. Алгоритм выборки данных аналогичен алгоритму для EntitySchemaQuery (см. "Чтение мультиязычных данных с помощью EntitySchemaQuery"):

  1. Если текущая культура пользователя является основной для приложения, то объект получает данные из основной таблицы.
  2. Если текущая культура пользователя является дополнительной, то объект получает данные из таблицы локализации. Если в таблице локализации для текущей культуры пользователя нет данных, то возвращаются данные из основной таблицы.

Далее приведены примеры использования одной из перегрузок методов Entity.FetchFromDB() и Entity.Save(), а также анализ результатов их выполнения для пользователя с основной (русской) и дополнительной (английской) культурами. Эти методы могут быть использованы, например, в методах пользовательского сервиса (см. "Как создать свой конфигурационный сервис").

Чтение данных

Пример кода получения данных из локализуемой колонки [Название] (Name) объекта схемы [Тип контрагента] (AccountType) на стороне сервера (C#):

// Пользовательское подключение.
var userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"];
// Получение схемы [Тип контрагента].
EntitySchema schema = userConnection.EntitySchemaManager.FindInstanceByName("AccountType");
// Создание экземпляра Entity (объекта).
Entity entity = schema.CreateEntity(userConnection);
// Коллекция имен колонок для выборки.
List<string> columnNamesToFetch = new List<string> {
    "Name",
    "Description"
};
// Получение данных для объекта, у которого значение колонки [Название] равно "Клиент".
entity.FetchFromDB("Name", "Клиент", columnNamesToFetch);
// Формирование и отправка ответа.
var name = String.Format("Name: {0}", entity.GetTypedColumnValue<string>("Name"));
return name;

Если содержащий этот код метод будет выполнен пользователем, у которого в профиле установлен язык по умолчанию, то в базу данных будет отправлен следующий запрос:

exec sp_executesql N'
SELECT
    [AccountType].[Name] [Name],
    [AccountType].[Description] [Description]
FROM
    [dbo].[AccountType] [AccountType] WITH(NOLOCK)
WHERE
    [AccountType].[Name] = @P1',N'@P1 nvarchar(6)',@P1=N'Клиент'

В приведенном выше запросе в параметре в парметре @P1 указывается значение "Клиент", по которому определяется нужная запись таблицы базы данных.

К СВЕДЕНИЮ

Посмотреть запрос можно, используя SQL Server Profiler (рис. 1).

Рис. 1. — Профилирование запроса в базу данных с помощью SQL Server Profiler

Если метод будет выполнен пользователем, у которого в профиле установлен дополнительный язык (например, английский), то в базу данных будет отправлен следующий запрос:

exec sp_executesql N'
SELECT
    ISNULL([SysAccountTypeLcz].[Name], [AccountType].[Name]) [Name],
    ISNULL([SysAccountTypeLcz].[Description], [AccountType].[Description]) [Description]
FROM
    [dbo].[AccountType] [AccountType] WITH(NOLOCK)
    LEFT OUTER JOIN [dbo].[SysAccountTypeLcz] [SysAccountTypeLcz] WITH(NOLOCK) ON ([SysAccountTypeLcz].[RecordId] = [AccountType].[Id]
    AND [SysAccountTypeLcz].[SysCultureId] = @P2)
WHERE
    [AccountType].[Name] = @P1',N'@P1 nvarchar(6),@P2 uniqueidentifier',@P1=N'Клиент',@P2='A5420246-0A8E-E111-84A3-00155D054C03'

В приведенном выше запросе в параметре @P1 указывается значение "Клиент", по которому определяется нужная запись основной таблицы базы данных. А в параметре @P2 — идентификатор дополнительной культуры из таблицы SysCulture, по которому будет определена соответствующая запись из таблицы локализации SysAcountTypeLcz.

Таким образом, значению переменной name для пользователя с русской культурой будет соответствовать "Клиент", а для пользователя с английской культурой — "Customer".

Сохранение локализованных данных

Для добавления и изменения локализованных данных предусмотрен метод Entity.SetColumnValue(). Данный метод может принимать как аргументы типа string, так и аргументы типа LocalizableString.

Сохранение локализованных данных с использованием string

При передаче аргумента типа string в метод Entity.SetColumnValue() используется следующий алгоритм сохранения:

  • при создании новой записи пользователем, для которого установлена дополнительная культура, данные добавляются и в основную таблицу и в таблицу локализации для дополнительной культуры;
  • при изменении уже существующего экземпляра Entity пользователем, для которого установлена дополнительная культура, результат сохраняется только в таблице локализации для дополнительной культуры;
  • при создании или изменении Entity пользователем, для которого установлена основная культура, данные добавляются или обновляются в основной таблице объекта Entity.

Пример кода сохранения данных с использованием строкового аргумента:

var userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"];
EntitySchema schema = userConnection.EntitySchemaManager.FindInstanceByName("AccountType");
Entity entity = schema.CreateEntity(userConnection);
// Установка для колонок значений по умолчанию.
entity.SetDefColumnValues();
// Установка значения для колонки [Название].
entity.SetColumnValue("Name", "Новый клиент");
// Сохранение.
entity.Save();
var name = String.Format("Name: {0}", entity.GetTypedColumnValue<string>("Name"));
return name;

При выполнении этого кода пользователем, в профиле которого установлен язык по умолчанию (русский), будет выполнен следующий запрос в базу данных:

exec sp_executesql N'
INSERT INTO [dbo].[AccountType]([Id], [Name], [CreatedOn], [CreatedById], [ModifiedOn], [ModifiedById], [ProcessListeners], [Description])
    VALUES(@P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8)',N'@P1 uniqueidentifier,@P2 nvarchar(12),@P3 datetime2(7),@P4 uniqueidentifier,@P5 datetime2(7),@P6 uniqueidentifier,@P7 int,@P8 nvarchar(4000)',@P1='3A820BC8-006D-42B7-A472-E331FBD73E20',@P2=N'Новый клиент',@P3='2017-02-10 09:40:23.0909251',@P4='410006E1-CA4E-4502-A9EC-E54D922D2C00',@P5='2017-02-10 09:40:23.0929256',@P6='410006E1-CA4E-4502-A9EC-E54D922D2C00',@P7=0,@P8=N''

В приведенном выше запросе в параметре @P2 указывается значение "Новый клиент", которое сохраняется в основной таблице базы данных.

Если в профиле пользователя установлен дополнительный язык (например, английский), то для сохранения данных с использованием строкового аргумента необходимо выполнить следующий код:

var userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"];
EntitySchema schema = userConnection.EntitySchemaManager.FindInstanceByName("AccountType");
Entity entity = schema.CreateEntity(userConnection);
entity.SetDefColumnValues();
entity.SetColumnValue("Name", "New Customer");
entity.Save();
var name = String.Format("Name: {0}", entity.GetTypedColumnValue<string>("Name"));
return name;

При выполнении этого кода будет выполнен такой же запрос в основную таблицу AccountType, как и для основной локализации, но в параметре @P2 будет указано значение "New Customer".

exec sp_executesql N'
INSERT INTO [dbo].[AccountType]([Id], [Name], [CreatedOn], [CreatedById], [ModifiedOn], [ModifiedById], [ProcessListeners], [Description])
    VALUES(@P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8)',N'@P1 uniqueidentifier,@P2 nvarchar(12),@P3 datetime2(7),@P4 uniqueidentifier,@P5 datetime2(7),@P6 uniqueidentifier,@P7 int,@P8 nvarchar(4000)',@P1='94052A88-499D-4072-A28A-6771815446FD',@P2=N'New Customer',@P3='2017-02-10 10:07:00.3454424',@P4='410006E1-CA4E-4502-A9EC-E54D922D2C00',@P5='2017-02-10 10:07:00.3454424',@P6='410006E1-CA4E-4502-A9EC-E54D922D2C00',@P7=0,@P8=N''

Кроме того, будет выполнен запрос в таблицу локализации:

exec sp_executesql N'
INSERT INTO [dbo].[SysAccountTypeLcz]([Id], [ModifiedOn], [RecordId], [SysCultureId], [Name])
    VALUES(@P1, @P2, @P3, @P4, @P5)',N'@P1 uniqueidentifier,@P2 datetime2(7),@P3 uniqueidentifier,@P4 uniqueidentifier,@P5 nvarchar(12)',@P1='911A721A-0E5A-4CC3-B6D9-9E5FE85FEC64',@P2='2017-02-10 10:07:00.3664442',@P3='94052A88-499D-4072-A28A-6771815446FD',@P4='A5420246-0A8E-E111-84A3-00155D054C03',@P5=N'New Customer'    

В приведенном запросе в параметре @P5 также указывается значение "New Customer".

Таким образом, в основную таблицу AccountType будет помещено значение, которое не соответствует основной локализации.

Для предотвращения подобных ситуаций необходимо использовать сохранение локализованных данных с использованием локализуемых строк.

Сохранение локализованных данных с использованием локализуемых строк

Пример кода сохранения данных с использованием аргумента — локолизуемой строки:

var userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"];
EntitySchema schema = userConnection.EntitySchemaManager.FindInstanceByName("AccountType");
Entity entity = schema.CreateEntity(userConnection);
entity.SetDefColumnValues();

// Создание локализуемой строки с локализованными значениями для разных культур.
var localizableString = new LocalizableString();
localizableString.SetCultureValue(new CultureInfo("ru-RU"), "Новый клиент ru-RU");
localizableString.SetCultureValue(new CultureInfo("en-US"), "New Customer en-US");

// Установка значения колонки с помощью локализуемой строки.
entity.SetColumnValue("Name", localizableString);
entity.Save();

// Результат будет выведен в текущей культуре пользователя.
var name = String.Format("Name: {0}", entity.GetTypedColumnValue<string>("Name"));
return name;

При выполнении этого кода, независимо от установленного в профиле пользователя языка, в БД будут отправлены:

1. В основную таблицу — запрос со значением "Новый клиент ru-RU" в аргументе @P2:

exec sp_executesql N'
INSERT INTO [dbo].[AccountType]([Id], [Name], [CreatedOn], [CreatedById], [ModifiedOn], [ModifiedById], [ProcessListeners], [Description])
    VALUES(@P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8)',N'@P1 uniqueidentifier,@P2 nvarchar(18),@P3 datetime2(7),@P4 uniqueidentifier,@P5 datetime2(7),@P6 uniqueidentifier,@P7 int,@P8 nvarchar(4000)',@P1='5AC81E4A-FCB2-4019-AE5B-0C485A5F65BD',@P2=N'Новый клиент ru-RU',@P3='2017-02-10 10:47:21.7471581',@P4='410006E1-CA4E-4502-A9EC-E54D922D2C00',@P5='2017-02-10 10:47:21.7511578',@P6='410006E1-CA4E-4502-A9EC-E54D922D2C00',@P7=0,@P8=N''

2. В таблицу локализации — запрос со значением "New Customer en-US" в аргументе @P5:

exec sp_executesql N'
INSERT INTO [dbo].[SysAccountTypeLcz]([Id], [ModifiedOn], [RecordId], [SysCultureId], [Name])
    VALUES(@P1, @P2, @P3, @P4, @P5)',N'@P1 uniqueidentifier,@P2 datetime2(7),@P3 uniqueidentifier,@P4 uniqueidentifier,@P5 nvarchar(18)',@P1='6EC9C205-7F8B-455E-BC68-3D9AA6D7B7C0',@P2='2017-02-10 10:47:21.9272674',@P3='5AC81E4A-FCB2-4019-AE5B-0C485A5F65BD',@P4='A5420246-0A8E-E111-84A3-00155D054C03',@P5=N'New Customer en-US'

ВАЖНО

Если код будет выполнен пользователем, в профиле которого установлена дополнительная культура, а в локализуемой строке не будет указано значение для основной культуры, то в основную таблицу AccountType будет добавлена запись для дополнительной культуры пользователя.

© Terrasoft 2002-2018.

Был ли данный материал полезен?

Как можно улучшить эту статью?