gifts2017

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

Опубликовал Сергей Карташев (Elisy) в раздел Программирование - Внешние компоненты

Появление в .Net framework технологии LinqToSql вызвало у многих и у меня, в том числе, резонный вопрос: «А зачем это нужно?». Ведь многие как использовали SQL-выражения или хранимые процедуры для доступа к MSSQL-базе, так и продолжают использовать их даже после выхода LinqToSql. Только недавно технология мне приглянулась с точки зрения прямого доступа к данным 1С:Предприятие 8.x, размещенным на сервере MS SQLServer. Дело в том, что нет абсолютно никакого соглашения о том, как 1С называет свои поля и таблицы, когда хранит их внутри базы данных. Именно здесь облегчит жизнь относительно новая технология Microsoft. К статье прилагается пример на Asp.Net MVC 2, демонстрирующий прямой доступ к данным 1С, работающей с установленной конфигурацией Управление Торговлей.

Появление в .Net framework технологии LinqToSql вызвало у многих и у меня, в том числе, резонный вопрос: «А зачем это нужно?». Ведь многие как использовали SQL-выражения или хранимые процедуры для доступа к MSSQL-базе, так и продолжают использовать их даже после выхода LinqToSql. Только недавно технология мне приглянулась с точки зрения прямого доступа к данным 1С:Предприятие 8.x, размещенным на сервере MS SQLServer. Дело в том, что нет абсолютно никакого соглашения о том, как 1С называет свои поля и таблицы, когда хранит их внутри базы данных. Именно здесь облегчит жизнь относительно новая технология Microsoft. К статье прилагается пример на Asp.Net MVC 2, демонстрирующий прямой доступ к данным 1С, работающей с установленной конфигурацией Управление Торговлей.

Предложенный к статье пример с открытым исходным кодом LinqTo1CWeb демонстрирует основные операции обращения к данным 1С: получение остатков по регистру, получение среза по ценовому регистру, соединение справочников и регистров в одну таблицу, их группировку.

Сразу нужно оговориться, что метод охватывает только прямое чтение данных. Прямая запись данных не рассматривается в связи с большой вероятностью ошибок. В случае прямой записи разработчику самому нужно будет заботиться о проведении документов по регистрам, регистрации изменений для распределенных баз и т.д.

Системные требования

Для просмотра примера вам ничего не нужно – только перейти по ссылке: http://linq-demo.1centerprise.com/

Если пример вас заинтересовал, для запуска примера у себя на компьютере вам понадобится только MSSQL. Пример, предложенный к статье, содержит SQL-скрипт в каталоге Setup для эмуляции некоторых справочников и регистров 1С:Предприятие.

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

  • 1С:Предприятие 8.x, работающее на MSSQL (возможно, в будущем будут охвачены другие типы СУБД)
  • Elisy .Net Bridge SDK, содержащий обработку LinqTo1C для генерации Dbml- и CS-файлов на основе метаданных 1С:Предприятие

[more]

 

Зачем нужен Linq-доступ к 1С:Предприятие

Linq-доступ к 1С:Предприятие является более родным с точки зрения .Net-программирования. Такой доступ экономит деньги на лицензии 1С, уменьшает число преобразований типов, не требует организации пула соединений, как при доступе через COM-соединения.

Предложенный способ может быть использован для наполнения контентом веб-сайтов (внутренних и внешних для предприятия), организации внутренних/внешних .Net-приложений, например, каталогов продукции.

Кто в данных хозяин

Прямой доступ к данным 1С рождает противоречие между законодательством Российской Федерации и лицензией 1С:Предприятие.

Позиция компании 1С по поводу прямого доступа следующая: «Нельзя обращаться к данным информационной базы напрямую, минуя уровень объектов работы с данными "1С:Предприятия" – например, при помощи средств СУБД».

Фирма 1С, закладывая такие пункты в лицензию, лукавит и сама нарушает законодательство РФ, а именно статьи: Статья 1334 п.1 "Исключительное право изготовителя базы данных" ГК РФ часть 4, а также Статья 25 п.1 и п.3 "Свободное воспроизведение программ для ЭВМ и баз данных. Декомпилирование программ для ЭВМ" Закона об авторском праве и смежных правах. В Гражданском Кодексе сказано:

"Изготовителю базы данных, создание которой (включая обработку или представление соответствующих материалов) требует существенных финансовых, материальных, организационных или иных затрат, принадлежит исключительное право извлекать из базы данных материалы и осуществлять их последующее использование в любой форме и любым способом".

Как еще можно обращаться к данным 1С

К 1С:Предприятие можно обращаться из .Net следующими способами:

  • COM-доступ,
  • Используя средство: web-extension,
  • Опубликовав 1С- веб-сервис,
  • Сделав экспорт в промежуточное хранилище, например, в Access;

COM-доступ – это традиционный вид доступа к данным 1С извне. Его можно использовать, но в .Net способ превращается в вереницу InvokeMember-вызовов. В .Net framework 4 ситуация улучшается через использование dynamic-типа. Но по гибкости и типизированности способ уступает LINQ. Сомневаюсь, что скорость работы данного способа будет выше прямого доступа к СУБД.

Web-расширение для 1С– это платный продукт, требующий дополнительной лицензии 1С. Ядро построено на WebForms, что может существенно затруднить использование в среде Asp.Net MVC.

Публикация веб-сервиса 1С требует особых знаний конфигурирования 1С. Кроме того, хорошим тоном при публиации веб-сервисов считается использование SSL-протокола, а это дополнительные проблемы получения сертификатов, конфигурации и доступа.

Четвертый вариант промежуточного хранилища лишает решение "свежести" данных. Измененные данные не будут моментально отображаться во внешнем приложении.

Проблема прямого доступа к 1С:Предприятие

Главная проблема в случае 1С – нет стандарта относительно наименования таблиц и полей в базе данных 1С. Если кто заглядывал внутрь базы данных, то мог увидеть множество таблиц с непонятными названиями вида:

 

Это обстоятельство не дает при доступе к данным из .Net использовать SQL-выражения, генерируемые в строках, и вызов их для получения DataReader и DataTable-объектов. Однажды сгенерированный запрос может потерять смысл и не работать при значимом обновлении конфигурации 1C или на конфигурации другого предприятия. В нашем случае запрос, объединяющий справочники Номенклатура, ЕдиницыИзмрения и регистр накопления ТоварыНаСкладах, может выглядеть так:

SELECT TOP 5 NomenclatureRef,
Nomenclature._Description, Nomenclature._Fld720RRef AS UnitRef,
Units._Description,
SUM(_Fld6354) AS Quantity, MAX(Units._Fld501) AS Weight
FROM
(
SELECT _Period, _Fld6349RRef AS WarehouseRef, _Fld6350RRef AS NomenclatureRef, _Fld6354
FROM _AccumReg6348
WHERE _Active = 1 AND _Period BETWEEN DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0) AND GetDate()
UNION ALL
SELECT _Period, _Fld6349RRef AS WarehouseRef, _Fld6350RRef AS NomenclatureRef, _Fld6354
FROM _AccumRegTotals6356
WHERE _Period = DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0)
) AS Balance
INNER JOIN _Reference53 AS Nomenclature ON Nomenclature._Marked = 0 AND NomenclatureRef = Nomenclature._IDRRef AND Nomenclature._IDRRef IN (SELECT _IDRRef FROM ##tt)
INNER JOIN _Reference35 AS Units ON Units._Marked = 0 AND Nomenclature._Fld720RRef = Units._IDRRef
GROUP BY NomenclatureRef,
Nomenclature._Description, Nomenclature._Fld720RRef,
Units._Description

А что, если в следующий раз 1С решит поменять имя регистра _AccumReg6348 на, например, _AccumReg7000 или поменяет где-нибудь название поля. Весь запрос перестанет работать.

В LinqToSql проблема остается – меняющиеся названия объектов БД, но ее значимость можно уменьшить, сгенерировав dbml/cs-файл из 1С, присвоив названия классам из метаданных конфигурации 1С. Если при обновлении конфигурации изменятся имена таблиц или полей БД, то необходимо будет заново сгенерировать dbml/cs-файл и поместить его, например, в App_Code-каталог без изменения другого кода программы.

Автоматическая генерация LinqToSql-файлов

Для работы механизмов LinqToSql необходимы специальные .Net – классы, которые генерируются компилятором автоматически на основе DBML-файла. DBML-файл – это XML-файл с определением соответствий между названиями таблиц, полей и названиями .Net-классов. DBML-файл можно посмотреть визуально:

Для облегчения генерации DBML-файла была создана внешняя обработка Elisy.LinqTo1CSql.81.epf для 1С:Предприятие. Поставляется она в составе с Elisy .Net Bridge SDK, так как обращается к функциональности .Net framework из 1C:Предприятие.

После указания строки подключения к СКЛСерверу, имени выгружаемого файла, имен выгружаемых объектов обработка Elisy.LinqTo1CSql на выходе получает dbml- и cs-файлы. CS-файл содержит все необходимые описания классов и может быть вставлен в .Net-проект. На DBML-файл можно смотреть из редактора Visual Studio.

После вставки CS-файла в проект получение остатков товаров по складу из кода C# будет выглядеть так:

public static IQueryable ПолучитьОстатки(УправлениеТорговлей dc, DateTime текущаяДата)
{
DateTime началоМесяца = dc.GetTable().Where(item => item._Period item._Period);

var товарыНаСкладахИтоги = from товарНаСкладе in dc.GetTable()
where (товарНаСкладе._Period == началоМесяца)
select new { Номенклатура = товарНаСкладе.Номенклатура, Количество = товарНаСкладе.Количество };

var товарыНаСкладахДетали = from товарНаСкладе in dc.GetTable()
where (началоМесяца select new { Номенклатура = товарНаСкладе.Номенклатура, Количество = товарНаСкладе._RecordKind == 0 ? товарНаСкладе.Количество : -1 * товарНаСкладе.Количество };

IQueryable списокНоменклатурыСОстатками = from товарНаСкладе in товарыНаСкладахИтоги.Concat(товарыНаСкладахДетали)
group товарНаСкладе by new { товарНаСкладе.Номенклатура } into группа
let количествоСумма = группа.Sum(элемент => элемент.Количество)
where количествоСумма > 0
select new Номенклатура { Ссылка = группа.Key.Номенклатура, Остаток = количествоСумма };

return списокНоменклатурыСОстатками;
}

Выводы

Представленный способ LinqToSql прямого доступа (чтения) к данным 1С имеет свои преимущества по отношению к другим способам. Стоимость его невысока. Скорость доступа к данным соизмерима или выше других способов. Данные всегда остаются актуальными и "свежими". Изменение данных в 1С приведет к немедленному изменению отображаемых данных в .Net-приложении.

Недостатки также присутствуют. Необходимость регенерации cs-файла при значимом изменении конфигурации. Ограниченное использование – невозможность использовать в файловом режиме работы 1С. Работа возможна только на чтение для уменьшения вероятности ошибок при записи данных в 1С.

Способ можно рекомендовать для наполнения контентом внутренних и внешних сайтов предприятий, организации каталогов продукции. LinqToSql конкурирует с web-доступом, появившимся в 1С:Предприятие 8.2. В 1С:Предприятие 8.2 веб-доступ лишен SEO-оптимизации, управления на уровне HTML/CSS-кода, AJAX-средствами, требует дополнительные лицензии, а 1С-программистам легче переходить с 8.1 версии на Asp.Net, чем на 8.2, «благодаря» ограничениям и мешанине из серверного и клиентского кода в каждой форме.

Предложенный к статье пример с открытым исходным кодом LinqTo1CWeb демонстрирует основные операции обращения к данным 1С: получение остатков по регистру, получение среза по ценовому регистру, соединение справочников и регистров в одну таблицу, их группировку. Пример написан на основе новой технологии Asp.Net MVC 2, дающей дополнительные преимущества в отношении гибкости и SEO-оптимизации.

 

// //

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Открытый Asp.Net MVC 2 пример
.zip 1,07Mb
16.10.13
53
.zip 1,07Mb 53 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Артур Аюханов (artbear) 19.10.09 09:06
А почему отнесена к разработкам, хотя это статья либо веб-закладка??
2. dushelov (Душелов) 19.10.09 09:16
Я бы отнес это к веб-закладке. Но никак не к статье.
3. Сергей Карташев (Elisy) 19.10.09 09:16
(1) Не знаю. Определена публикация: веб-закладка
4. Герман (German) 19.10.09 09:32
8) Да, не знал про эту технологию...
ИМХО Проще создать представления(View), их можно не только через С# использовать, а на простом T-SQL. Явно было представлено в ранних версиях Ei
5. Сергей Карташев (Elisy) 19.10.09 10:11
(4) Для конкретного случая .net framework + MS SQL не проще. Для остальных случаев, куда не дошел Linq, скорее всего проще, спорить не буду.
Разработчики C# могут оценить:
Следующая C# конструкция свяжет справочники Номенклатура+ЕдиницыИзмерения, задаст параметр отбора, а на выходе выдаст готовые объекты Товар:
var nomenclatureModel = from Номенклатура in dc.GetTable<СправочникЕдиницыИзмерения>().Where(item => item.Родитель == nom.Ссылка)
join Еи in dc.GetTable<СправочникЕдиницыИзмерения>() on Номенклатура.ЕдиницаХраненияОстатков equals Еи.Ссылка
select new Товар { Ссылка = new Guid(Номенклатура.Ссылка.ToArray()), Наименование = Номенклатура.Наименование, ЕИ = Еи.Наименование };

При этом система .net framework внутри себя сгенерирует SQL-выражение, сделает запрос к БД, преобразует данные в нужный формат Товар:
{SELECT [t0].[_IDRRef], [t0].[_Description] AS [Наименование], [t1].[_Description] AS [ЕИ]
FROM [dbo].[_Reference53] AS [t0]
INNER JOIN [dbo].[_Reference35] AS [t1] ON [t0].[_Fld720RRef] = [t1].[_IDRRef]
WHERE [t0].[_ParentIDRRef] = @p0
}
6. dushelov (Душелов) 19.10.09 18:31
Идея, конечно, хорошая, но только для чтения. Писать бы я не стал.
7. gilv (Gilev.Vyacheslav) 19.10.09 20:59
http://v8.1c.ru/predpriyatie/questions_licence.htm
Лицензионное соглашение не позволяет использовать недокументированные фирмой "1С" средства для построения решений на платформе 1С:Предприятие. Это означает, что средства СУБД (или любые другие внесистемные средства) можно использовать только в том случае, если документация по продуктам линейки "1С:Предприятие" (включая ИТС) содержит явную рекомендацию использовать данное средство для решения данной задачи.

Во всех остальных случаях лицензионное соглашение позволяет использовать для построения решений только штатные средства платформы. В частности, можно обращаться к данным информационной базы только при помощи объектов "1С:Предприятия", специально предназначенных для работы с данными (запросы, справочники, документы и т.д.). Нельзя обращаться к данным информационной базы напрямую, минуя уровень объектов работы с данными "1С:Предприятия" - например при помощи средств СУБД или при помощи внешних компонент, которые реализуют прямой доступ к СУБД. Это ограничение распространяется на любые действия с данными, в том числе на изменение их структуры, а так же на чтение или изменение самих данных информационной базы или служебных данных "1С:Предприятия".

Данное ограничение необходимо для обеспечения стабильности работы механизмов системы, осуществления поддержки и возможности перехода на новые версии "1С:Предприятия".
Душелов; +1 Ответить 6
8. gilv (Gilev.Vyacheslav) 19.10.09 21:00
так что у этого "мало исследованного" способа еще другой побочный эффект, с новыми правилами 1с можно огрести :D
Душелов; +1 Ответить 1
9. Сергей Карташев (Elisy) 20.10.09 07:48
(7)(8) Получить xml-файл на платформе 1С - это не нарушение правил 1С. Запись xml-файла - это документированные функции. Внешние обработки - это также построенные по технологии 1С решения. Запуск такой обработки не противоречит правилам 1С. Все остальное - вотчина .net framework, Visual Studio, SQL Server и Microsoft.
Компании 1С следует обратиться с официальным письмом к корпорации Microsoft с требованием блокировать в новых версиях MSSql, .net framework и Visual Studio доступ к базам данных 1С. А равно как и в срочном порядке выпустить сервис паки к существующим версиям, реализующим такие ограничения.
Продукты Microsoft лицензируются отдельными соглашениями и компания 1С не вправе предъявлять подобного рода претензии к ним.
10. Сергей Карташев (Elisy) 20.10.09 07:51
(6) Я бы тоже записывать пока не стал. Подождал бы, пока другие запишут и скажут результат :)
11. Артур Аюханов (artbear) 20.10.09 08:16
(7) ОФФ. ИМХО эта лицензия в какой-то мере нарушает закон об авторском праве :(
Но у 1С явно юристы лучше, чем у тех, кто попробует с этим побороться :(
12. Евгений Мартыненков (JohnyDeath) 20.10.09 09:23
(7) Офигеть. А это нормально? СУБД-то не от 1С, с чего это вдруг я не могу выбирать из неё данные своими средствами?
Вячеслав, у тебя на сайте много хорошего и полезного материала по 1С 8, где ты используешь не только 1С для оценки эффективности и оптимизации работы базы. За это ты тоже можешь отгрести?
13. Сергей Карташев (Elisy) 20.10.09 13:07
(7) Данное требование лицензионного соглашения противоречит Статье 1334 п.1 "Исключительное право изготовителя базы данных" ГК РФ часть 4, а также Статье 25 п.1 и п.3 "Свободное воспроизведение программ для ЭВМ и баз данных. Декомпилирование программ для ЭВМ" Закона об авторском праве и смежных правах.
В Гражданском Кодексе сказано:
"Изготовителю базы данных, создание которой (включая обработку или представление соответствующих материалов) требует существенных финансовых, материальных, организационных или иных затрат, принадлежит исключительное право извлекать из базы данных материалы и осуществлять их последующее использование в любой форме и любым способом".
14. gilv (Gilev.Vyacheslav) 20.10.09 17:20
(12) да, мне тоже может попасть, по этой причине обработку locks уже убрал с сайта
15. gilv (Gilev.Vyacheslav) 20.10.09 17:25
(13) российский гражданский кодекс какую предусматривает ответственность за нарушение?
а я вот докадываюсь, чем грозит разборки с 1С,
сейчас это основной обвинитель по делам с нарушениями ЛС в России
16. Сергей Карташев (Elisy) 21.10.09 07:07
(15) Гражданский кодекс ничего не говорит об ответственности. За это отвечает административный кодекс, который изучать нужно. Даже при самом худшем раскладе, до которого доведут самые лучшие адвокаты 1С - нарушение данного пункта лицензионного соглашения не уголовное преступление. А на месте таких адвокатов впутываться в дела с сомнительным результатом - работа неблагодарная. Другой вопрос, кто-нибудь знает прецеденты конкретно по таким делам, доведенным до суда?
17. Rabajaba Caspersky (Rabajaba) 23.06.10 10:43
"1С-программистам легче переходить с 8.1 версии на Asp.Net, чем на 8.2, «благодаря» ограничениям и мешанине из серверного и клиентского кода в каждой форме" это минус, хотя статья понравилась.
"мешанине" это вы как-то неверно готовите. Мне наоборот нравится, что 1С теперь УЧИТ писать архитектурно грамотно, разбивая всю работу БД на клиента и сервера. Что, в свою очередь, заставляет думать об объемах трафика и количестве вызовов между клиентом и сервером, что было довольно сложно оценить в 8.1.
П.С. Серверный код для формы никто не заставляет писать в модуле формы.
18. anna savosina (soe) 22.08.11 09:32
при открытии обработки возникает ошибка:
{Форма.Форма(7)}: Ошибка при вызове метода контекста (ЗагрузитьВнешнююКомпоненту): Ошибка при загрузке внешней компоненты
ЗагрузитьВнешнююКомпоненту("C:\Program Files\Elisy .Net Bridge SDK\Elisy.NetBridge.dll");
по причине:
Ошибка при загрузке внешней компоненты

Не подскажите причину?
19. Сергей Карташев (Elisy) 10.09.11 11:36
soe пишет:
при открытии обработки возникает ошибка: {Форма.Форма(7)}: Ошибка при вызове метода контекста (ЗагрузитьВнешнююКомпоненту): Ошибка при загрузке внешней компоненты ЗагрузитьВнешнююКомпоненту("C:\Program Files\Elisy .Net Bridge SDK\Elisy.NetBridge.dll"); по причине: Ошибка при загрузке внешней компоненты

Не подскажите причину?

Нужно проверить:
1. Установлен .Net framework 3.5 SP1?
2. На Windows 7 с включенным UAC нужно устанавливать .Net Bridge с правами администратора. Только в этом случае Elisy.NetBridge.dll сможет прописаться в реестре.
20. maksar maksar (maksar) 25.11.11 03:49
Интересно почитать, спасибо.
21. Сергей Карташев (Elisy) 25.11.11 06:57
(20) Спасибо. Читайте статью на эту же тему в октябрьском номере журнала MSDeveloper
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа