Статья описывает методику генерации dbml-файла для данных СУБД SQLServer 1С:Предприятие и последующего прямого обращения к ним. Dbml-файл далее с успехом может использоваться в ASP.Net 3.5 для отображения актуальных данных. Это малоисследованный способ, который может иметь как невыявленные недостатки, так и достоинства. Будьте предельно внимательны при изменении данных, так как ошибки могут сделать конфигурацию 1С неработоспособной.
Все началось с задачи: реализовать веб-сайт – электронный каталог товаров. Данные в веб-сайт должны поступать из 1С-конфигурации Управление Торговлей. Управление Торговлей работает в клиент-серверном варианте под управлением СУБД MS SQL.
Выбор системы доступа к данным
1С можно приобщить к веб-технологиям следующими способами:
- Используя продукты: web-extension, 1С:Битрикс,
- Опубликовав родной для 1С веб-сервис,
- Сделав экспорт в промежуточное хранилище, родное для веб-сайта, например, в Access,
- Прямым доступом к данным: запрос к СКЛСерверу или технология Linq;
Web-расширение для 1С и 1С:Битрикс – это платные продукты, написанные специально для этого. Боюсь ошибиться, но их ядра построены на WebForms, что может существенно затруднить использование в среде Asp.Net MVC. Их нет смысла использовать для достаточно простых задач.
Публикация веб-сервиса 1С требует особых знаний конфигурирования 1С. Кроме того, хорошим тоном при публиации веб-сервисов считается использование SSL-протокола, а это дополнительные проблемы получения сертификатов, конфигурации и доступа.
Третий вариант промежуточного хранилища лишит сайт прямого доступа к данным, а значит "свежести" этих данных.
Вариант прямого доступа к данным через SQLServer понравился больше всех. Решено было проработать вначале его. Особых забот относительно выбора технологии реализации не возникало – это Asp.Net, если возможно Asp.Net MVC.
Выбор способа прямого доступа к данным 1С
Как ни странно, но и при прямом доступе к данным SQL Server есть выбор в способе. Есть и связанные с 1С проблемы, которые необходимо решать.
Главная проблема в случае 1С – нет стандарта относительно наименования таблиц и полей в базе данных 1С. Если кто заглядывал внутрь базы данных, то мог увидеть множество таблиц с непонятными названиями вида:

Это обстоятельство не дает при доступе к данным использовать 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-файл из 1С, присвоив названия классам из метаданных конфигурации 1С. Если при обновлении конфигурации изменятся имена таблиц или полей БД, то необходимо будет только заново сгенерить dbml-файл и поместить его в App_Code-каталог без изменения кода классов программы.
Внешняя обработка Elisy.LinqTo1CSql.81.epf
На этом этапе появляется необходимость во внешней обработке, которая объединит метаданные 1С и свойства объектов СУБД, генерирует на выходе dbml-файл.
Для генерации dbml-файла была создана обработка Elisy.LinqTo1CSql.81.epf, которая в дальнейшем войдет в состав продукта Elisy .Net Bridge. Здесь находится ее альфа-версия, генерящая dbml-описания жестко для справочников Номенклатура, ЕдиницыИзмерения и регистра накопления ТоварыНаСкладах. Обработка требует заргистрированный внешний компонент Elisy.NetBridge.dll (версии 2.3). Это внешний вид обработки:

Использование результирующего dbml-файла
В результате работы обработки Elisy.LinqTo1CSql.81.epf появляется dbml-файл, который в Visual Studio выглядит так:

Обработка создала dbml с определением пространства имен вида: Elisy.LinqTo1CSql.<имя конфигурации>. В дальнейшем обращение из C# можно выполнить так (здесь приведено определение класса контроллера из Asp.Net MVC):
using System.Data.Linq;
using System.Linq.Expressions;
using Elisy.LinqTo1CSql.УправлениеТорговлейДляКазахстана;
[HandleError]
public class ProductController : Controller
{
[OutputCache(Duration = 60, VaryByParam = "none")]
public ActionResult Item(string parentname, string names)
{
УправлениеТорговлейДляКазахстана dc = new УправлениеТорговлейДляКазахстана(ConfigurationManager.ConnectionStrings["GalTUS2ConnectionString"].ConnectionString);
Table<СправочникНоменклатура> table = dc.GetTable<СправочникНоменклатура>();
byte[] parentId = new Guid("00000000-0000-0000-0000-000000000000").ToByteArray();
var tableByParentIDRef = table.Where(item => item.Родитель == parentId);
...
}
}
Выводы
Представленный способ прямого доступа к данным 1С имеет свои преимущества по отношению к другим способам. Стоимость его невысока. Скорость доступа к данным соизмерима или выше других способов. Данные всегда остаются "свежими".
Недостатки также присутствуют. Необходимость регенерации dbml-файла при значимом изменении конфигурации. Ограниченное использование – невозможность использовать в файловом режиме работы 1С. Нужно быть предельно внимательными при изменении данных, так как ошибки могут привести к неработоспособной конфигурации 1С.
Elisy.LinqTo1CSql.81.Alpha.epf (15,88 kb)
Elisy.NetBridge.dll (129,00 kb)