Code First и Linq to EF на примере 1С версии 8.3. Часть II

Публикация № 402038 24.09.15

Разработка - Практика программирования

Code First Linq

Эта статья - продолжение http://infostart.ru/public/393228/ Там же лежит и обработка для генерации C# файлов. Суть та же, что и для 7.7, но есть особенности.

Здесь лежит практика использования //infostart.ru/public/402433/

Начнем с класса предка.

 

  public   class   СсылочныйТип

    {

 

        [Key]

        [Column("_IDRRef")]

        [MaxLength(16)]

        public  byte[] ID { get; set; }

 

        [NotMapped]

        public  virtual  int  НомерТаблицы { get { return 0; } }

    }

 

Номер таблицы нам понадобится для неопределенных типов.

Кроме того, мы сможем сделать дженерик метод

 

public TEntity ПолучитьСсылочныйЭлемент<TEntity>(byte[] ID) where TEntity : СсылочныйТип

        {

 

 

            var query = from спр in this.Set<TEntity>()

                         where спр.ID == ID

                         select спр;

            return query.SingleOrDefault<TEntity>();

 

        }

 

Пока реализованы справочники, табличные части и перечисления

Это описание Справочника предка

  public  abstract  class  СправочникПредок :СсылочныйТип

    {

     [Column("_Version", TypeName = "timestamp")]

        [MaxLength(8)]

        [Timestamp]

        public byte[] Версия { get; set; }

       

        [Column("_Marked")]

        [Required]

        [MaxLength(1)]

        public byte[] ПометкаУдаленияId { get; set; }

 

        [Column("_PREDEFINEDID")]

        [Required]

        [MaxLength(16)]

        public byte[] ПредопределенныйId { get; set; }

 

        [NotMapped]

        public bool ПометкаУдаления

        {

            get { return ПометкаУдаленияId.ВБулево(); }

 

            set

            {

                ПометкаУдаленияId = value.БулевоВМассив();

            }

        }

 

        public  abstract  string Наименование { get; set; }

        public  abstract  byte[] ЭтоГруппаId { get; set; }

        public  abstract  object ПолучитьКод();

        public  abstract  string Вид();

        public  bool  ЭтоГруппа() { return  ЭтоГруппаId.ВБулево(); }

 

 

    }

 

А Это табличной части

public  partial  class  ТабличнаяЧастьПредок

    {

 

        virtual  public  byte[] СсылкаID { get; set; }

 

        [Key]

        [Column("_KeyField", Order = 1)]

        [MaxLength(4)]

        publicbyte[] KeyField { get; set; }

        virtual  public  int  НомерСтроки { get; set; }

 

 

    }

 

На основании этих предков можно уже создавать потомков

 

Я сделал несколько тестовых справочников со всевозможными типами.

Например

 

[Table("_Reference10")]

public  partial  class  Тестовый:СправочникПредок

{

public  const  int  НомТаблицы=10;

public  const  string  ВидСпр="Тестовый";

[NotMapped]

override  public  byte[] ЭтоГруппаId { get{return КонстантыБД.Ложь;} set{} }

 

[Column("_CODE",TypeName = "nvarchar")]

[Required]

[StringLength(9)]

 public  string  Код { get; set; }

 

[Column("_DESCRIPTION",TypeName = "nvarchar")]

[Required]

[StringLength(25)]

override  public  string  Наименование { get; set; }

 

 

[Column("_Fld12",TypeName = "nvarchar")]

[StringLength(20)]

public  string  Строка { get; set; }

 

[Column("_Fld46",TypeName = "nchar")]

[StringLength(10)]

public  string  СтрокаФиксированная { get; set; }

 

[Column("_Fld47",TypeName = "ntext")]

public  string  СтрокаДлинная { get; set; }

 

[Column("_Fld13",TypeName = "numeric")]

[Required]

public System.Decimal Число { get; set; }

 

[Column("_Fld14",TypeName = "numeric")]

[Required]

public System.Int64 Целое { get; set; }

 

[Column("_Fld15")]

[Required]

public  DateTime  Дата { get; set; }

 

[Column("_Fld16")]

[Required]

[MaxLength(1)]

public  byte[] БулевоId { get; set; }

 

[Column("_Fld17",TypeName = "image")]

[Required]

public  byte[] ХранилищеЗначения { get; set; }

 

[Column("_Fld18")]

[Required]

[MaxLength(16)]

public  byte[] УникальныйИдентификатор { get; set; }

public  НеопределенныеТипы.ЛюбаяСсылка_Fld19 ЛюбаяСсылкаId { get; set; }

 

[Column("_Fld20RRef")]

[Required]

[MaxLength(16)]

public  byte[] ПеречислениеДляТестовId { get; set; }

public  НеопределенныеТипы.РевизитВсеТипы_Fld37 РевизитВсеТипыId { get; set; }

public  НеопределенныеТипы.НеопределенныйНеССылочный_Fld40 НеопределенныйНеССылочныйId { get; set; }

 

[Column("_Fld48RRef")]

[Required]

[MaxLength(16)]

public  byte[] РеквизитСправочникId { get; set; }

 

[Column("_Fld49RRef")]

[Required]

[MaxLength(16)]

public  byte[] РеквизитДокументId { get; set; }

 

override  public string ToString(){returnКод.ToString();}

       [NotMapped]

public  bool  Булево {

   get { return БулевоId.ВБулево(); }

 

 set

   {

  БулевоId = value.БулевоВМассив();

    }

}

       [NotMapped]

public  object  ЛюбаяСсылка { get{return КонстантыБД.ПолучитьЗначениеНеопределенногоТипа(ЛюбаяСсылкаId);} set{КонстантыБД.УстановитьЗначениеНеопределенногоТипа(value,ЛюбаяСсылкаId);} }

virtual  public  Перечисление.ДляТестовСсылка ПеречислениеДляТестов { get; set; }

       [NotMapped]

public  object  РевизитВсеТипы { get{return КонстантыБД.ПолучитьЗначениеНеопределенногоТипа(РевизитВсеТипыId);} set{КонстантыБД.УстановитьЗначениеНеопределенногоТипа(value,РевизитВсеТипыId);} }

       [NotMapped]

public  object  НеопределенныйНеССылочный { get{return КонстантыБД.ПолучитьЗначениеНеопределенногоТипа(НеопределенныйНеССылочныйId);} set{КонстантыБД.УстановитьЗначениеНеопределенногоТипа(value,НеопределенныйНеССылочныйId);} }

virtual  public  Справочник.Номенклатура РеквизитСправочник { get; set; }

[InverseProperty("Владелец")]

publicICollection<Справочник.ПодчиненныйОдинВладелец> ПодчиненныеПодчиненныйОдинВладелец { get; set; }

[InverseProperty("Ссылка")]

publicICollection<ТЧ.ТабЧасть> ПодчиненныеТабЧасть { get; set; }

public  override  int  НомерТаблицы { get { return НомТаблицы; } }

public  override  string  Вид(){return ВидСпр;}

public  override  object  ПолучитьКод(){return Код;}

 

}

 

В отличие от 7.7 здесь введены новые типы для неопределенных типов.

Например

 

[ComplexType]

public  class  РевизитВсеТипы_Fld37:НеопределенныйТип,НеопределенныйТипБулево,НеопределенныйТипЧисло,НеопределенныйТипДата,НеопределенныйТипСтрока,НеопределенныйТипСсылочный

{

[Column("_Fld37_TYPE")]

[Required]

[MaxLength(1)]     

override  public byte[] Тип { get; set; }

 

[Column("_Fld37_L")]

[Required]

[MaxLength(1)]

public byte[] БулевоId { get; set; }

 

[Column("_Fld37_N",TypeName = "numeric")]

[Required]

public  decimal  Число { get; set; }

 

[Column("_Fld37_T")]

[Required]

public  DateTime  Дата { get; set; }

 

[Column("_Fld37_S",TypeName = "nvarchar")]

[StringLength(42)]

public  string  Строка { get; set; }

 

    [Column("_Fld37_RTREF")]

        [Required]

        [MaxLength(4)]

      public  byte[] НомерТаблицы { get; set; }

    

[Column("_Fld37_RRREF")]

       [Required]

        [MaxLength(16)]

        public  byte[] Ссылка { get; set; }

 

       [NotMapped]

public bool Булево {

   get { return БулевоId.ВБулево(); }

 

 set

   {

  БулевоId = value.БулевоВМассив();

    }

}

 

}

 

 

Такие типы помечаются атрибутом [ComplexType]

Что позволяет использовать их так

 

public НеопределенныеТипы.РевизитВсеТипы_Fld37 РевизитВсеТипыId { get; set; }

 

и получение, и установка объекта

[NotMapped]

public  object  РевизитВсеТипы { get{return КонстантыБД.ПолучитьЗначениеНеопределенногоТипа(РевизитВсеТипыId);} set{КонстантыБД.УстановитьЗначениеНеопределенногоТипа(value,РевизитВсеТипыId);} }

 

Так как  состав типа может быть различным для получения и установки полей, я ввел интерфейсы

 

public  class  НеопределенныйТип

    {

        virtual  public  byte[] Тип { get; set; }

    }

 

    public  interface  НеопределенныйТипЧисло

    {

        Decimal  Число { get; set; }

    }

 

    public  interface  НеопределенныйТипСтрока

    {

        string  Строка { get; set; }

    }

 

    public  interface  НеопределенныйТипБулево

    {

        bool  Булево { get; set; }

    }

 

    public  interface  НеопределенныйТипДата

    {

        DateTime  Дата { get; set; }

    }

 

    public  interface  НеопределенныйТипСсылочный

    {

        byte[] НомерТаблицы { get; set; }

        byte[] Ссылка { get; set; }

 

    }

 

 

Теперь можно написать методы чтения и установки объектов

 

public  static  object ПолучитьЗначениеНеопределенногоСсылочного(НеопределенныйТип ВладелецId)

        {

            var НТС=ВладелецId as НеопределенныйТипСсылочный;

            Func<byte[], object> значение;

            if (ОбъектыПоТипу.TryGetValue(НТСомерТаблицы.byteArrayToInt(), out значение))

                return значение(НТС.Ссылка);

 

                    return null;

        }

        public  static  object ПолучитьЗначениеНеопределенногоТипа(НеопределенныйТип ВладелецId)

        {

            var тип = ВладелецId.ТипБайт();

 

            switch(тип)

            {

                case 1: return  null;

                case 2: return (ВладелецId as НеопределенныйТипБулево).Булево;

                case 3: return (ВладелецId as НеопределенныйТипЧисло)исло;

                case 4: return (ВладелецId as НеопределенныйТипДата)ата;

                case 5: return (ВладелецId as НеопределенныйТипСтрока)трока;

                case 8: return ПолучитьЗначениеНеопределенногоСсылочного(ВладелецId);

            }

            return  null;

        }

 

 

ОбъектыПоТипу это хэш таблица, которая заполняется так

 

public  partial  class  КонстантыБД

    {

         static КонстантыБД()

        {

            ОбъектыПоТипу = new  Dictionary<int, Func<byte[], object>>();

 

 

ОбъектыПоТипу.Add(Справочник.Тестовый.НомТаблицы,

      (ключ) => { return БДолучитьСсылочныйЭлемент<Справочник.Тестовый>(ключ); }

      );

 

ОбъектыПоТипу.Add(Справочник.Номенклатура.НомТаблицы,

      (ключ) => { return БДолучитьСсылочныйЭлемент<Справочник.Номенклатура>(ключ); }

      );

 

ОбъектыПоТипу.Add(Справочник.ПодчиненныйОдинВладелец.НомТаблицы,

      (ключ) => { return БДолучитьСсылочныйЭлемент<Справочник.ПодчиненныйОдинВладелец>(ключ); }

      );

 

ОбъектыПоТипу.Add(Справочник.ПодчиненныйДваВладельца.НомТаблицы,

      (ключ) => { return БДолучитьСсылочныйЭлемент<Справочник.ПодчиненныйДваВладельца>(ключ); }

      );

 

ОбъектыПоТипу.Add(Справочник.Справочник1.НомТаблицы,

      (ключ) => { return БДолучитьСсылочныйЭлемент<Справочник.Справочник1>(ключ); }

      );

 

 ОбъектыПоТипу.Add(Перечисление.ДляТестовСсылка.НомТаблицы,

                   (ключ) => { var значение = БДолучитьСсылочныйЭлемент<Перечисление.ДляТестовСсылка>(ключ);

                   if (значение == null)

                       retur nnull;

 

                   return значениеначение;

                  

                   }

                   );

 

          

         }

    }

 

 

Ну и реализация установки значений

 

public  static  void УстановитьЗначениеНеопределенногоТипа(object value,НеопределенныйТип ВладелецId)

        {

           

            ОчиститьСтароеЗначениеНеопределенного(ВладелецId);

            if (value==null)

            {

                ВладелецId.Тип[0] =1;

                return;

            }

       

            var тип=value.GetType();

            if (тип==typeof(bool))

            {

                ВладелецId.Тип[0] =2;

                (ВладелецId as  НеопределенныйТипБулево)улево = (bool)value;

 

            }

            elseif (тип == typeof(decimal))

            {

                ВладелецId.Тип[0]=3;

                (ВладелецId as  НеопределенныйТипЧисло).Число = (decimal)value;

 

            }

            elseif (тип == typeof(DateTime))

            {

                ВладелецId.Тип[0] = 4;

                (ВладелецId as  НеопределенныйТипДата).Дата = (DateTime)value;

 

            }

            elseif (тип == typeof(string))

            {

                ВладелецId.Тип[0] =5;

                (ВладелецId as  НеопределенныйТипСтрока).Строка = (string)value;

 

            }

            elseif (value is  СсылочныйТип)

            {

                ВладелецId.Тип[0] = 8;

                varзначение = value as  СсылочныйТип;

               

                var Владелец = ВладелецId as  НеопределенныйТипСсылочный;

                ВладелецомерТаблицы = значение.НомерТаблицы.intToByteArray();

                Владелецсылка = значение.ID;

 

            }

        }

 

 

 

Еще одна особенность это описание перечислений

 

namespace Linq21c8.Перечисление

{

    [Table("_Enum11")]

    public  partial  class  ДляТестовСсылка :СсылочныйТип

    {

        [Column("_ENUMORDER", TypeName = "numeric")]

 

        [Required]

        public  ДляТестов Значение { get; set; }

 

 

        public  const  int  НомТаблицы = 11;

        public  override  int  НомерТаблицы { get { returnНомТаблицы; } }

 

    }

    public  enum  ДляТестов

    {

        Первый // Первый

        , Второй // Второй

    }

    public  static  class  РасширениеПеречисления

    {

 

        public  static  ДляТестовСсылка ПолучитьСсылку(thisДляТестов ID)

        {

            var БД = КонстантыБДД;

            var query = from спр in БДляТестов_Перечисл

                        where  спр.Значение == ID

                        select  спр;

            return query.SingleOrDefault();

        }

 

    }

 

}

Так в CodeFirs числовому значению можно задать тип перечисления

 

        public  ДляТестов  Значение { get; set; }

 

 

Кроме того реализован класс для расширения перечисления

 

Пример использования

 

  var перечисление_Первый = Перечисление.ДляТестов.Первый.ПолучитьСсылку();

 

  var перечисление_Второй = Перечисление.ДляТестов.Второй.ПолучитьСсылку();

 

   foreach (var  спр  in qr2)

  {

    спртрокаФиксированная = "";

    спрелое = ++целое;

 

      if (целое % 2 == 1)

        спреречислениеДляТестов = перечисление_Первый;

       else

        спреречислениеДляТестов = перечисление_Второй;

 

 

     бд.Entry(спр).State = System.Data.Entity.EntityState.Modified;

 

    }

 

Также можно задавать условие

 

var qr2 = from Номенклатура in бдестовый_Спр

 where НоменклатураеречислениеДляТестов.Значение==Перечисление.ДляТестов.Второй

 select Номенклатура;

 

 

Есть особенность для ComplexType

 

   public partial class Тестовый : СправочникПредок

    {

        public partial class НеопределенныеТипы

        {

            [ComplexType]

            public class ЛюбаяСсылка_Fld19 : НеопределенныйТип, НеопределенныйТипСсылочный

            {

                [Column("_Fld19_TYPE")]

                [Required]

                [MaxLength(1)]

                override public byte[] Тип { get; set; }

 

                [Column("_Fld19_RTREF")]

                [Required]

                [MaxLength(4)]

                public byte[] НомерТаблицы { get; set; }

 

                [Column("_Fld19_RRREF")]

                [Required]

                [MaxLength(16)]

                public byte[] Ссылка { get; set; }

 

            }

       }

  }

 

 

public partial class  Тестовый : СправочникПредок

    {

        public partial class  ТЧ

        {

            public partial class  НеопределенныеТипы

            {

                [ComplexType]

                public class  ЛюбаяСсылка_Fld52 : НеопределенныйТип, НеопределенныйТипСсылочный

                {

                    [Column("_Fld52_TYPE")]

                    [Required]

                    [MaxLength(1)]

                    override public byte[] Тип { get; set; }

 

                    [Column("_Fld52_RTREF")]

                    [Required]

                    [MaxLength(4)]

                    public byte[] НомерТаблицы { get; set; }

 

                    [Column("_Fld52_RRREF")]

                    [Required]

                    [MaxLength(16)]

                    public byte[] Ссылка { get; set; }

 

                }

 

            }

 

 

        }

    }



Есть поле в разных типах ЛюбаяСсылка, но в базе все названия [ComplexType] должны быть уникальными.
Поэтому добавляю номер таблицы для неопределенных владельцев и номер поля для неопределенных полей

 

 

Теперь посмотрим на реализацию табличной части

public   partial    class   ТабличнаяЧастьПредок

    {

 

        virtual  public  byte[] СсылкаID { get; set; }

 

        [Key]

        [Column("_KeyField", Order = 1)]

        [MaxLength(4)]

        public byte[] KeyField { get; set; }

        virtual  public  int  НомерСтроки { get; set; }

 

 

    }

 

 

[Table("_Reference10_VT31")]

public  partial  class  ТабЧасть:ТабличнаяЧастьПредок

{

   [Key]

   [Column("_Reference10_IDRRef", Order = 0)]

   [MaxLength(16)]

  override  public byte[] СсылкаID { get; set; }

 

    [Key]

   [Column("_LineNo32", Order = 2, TypeName = "numeric")]

   override  public  int  НомерСтроки { get; set; }

 

[Column("_Fld33RRef")]

[Required]

[MaxLength(16)]

public  byte[] НоменклатураId { get; set; }

 

[Column("_Fld34",TypeName = "numeric")]

[Required]

public System.Int64 Количество { get; set; }

 

[Column("_Fld35",TypeName = "numeric")]

[Required]

public System.Decimal Сумма { get; set; }

public   НеопределенныеТипы.ЛюбаяСсылка_Fld52 ЛюбаяСсылкаId { get; set; }

 

virtual  public  Справочник.Тестовый Ссылка { get; set; }

virtual  public  Справочник.Номенклатура Номенклатура { get; set; }

       [NotMapped]

public  object  ЛюбаяСсылка { get{returnКонстантыБД.ПолучитьЗначениеНеопределенногоТипа(ЛюбаяСсылкаId);} set{КонстантыБД.УстановитьЗначениеНеопределенногоТипа(value,ЛюбаяСсылкаId);} }

 

}

 

 

Так, в ТЧ три ключевых поля СсылкаID, KeyField и НомерСтроки

Ссылка это владелец табличной части.

 

Основной метод, создающий описание полей, выглядит так

 

Процедура ПрописатьРеквизит(тип,ИмяСвойства,ПолеБД,Реквизит,ТекстПолей, ТекстВиртуальных,ТипВладельца)
    ИмяРеквизита=ИмяСвойства;
    СтрВиртуал="";
    Required="
    |[Required]";
    Стр="";
    TypeName="";
    Если Тип=Тип("Булево") Тогда
        Стр=  "[MaxLength(1)]";
        ИмяРеквизита=ИмяСвойства+"Id";
        ТипРеквизита= "byte[]";
        СтрВиртуал= СоздатьВиртуальноеБулево(ИмяСвойства);



    ИначеЕсли Тип=Тип("Число") Тогда
        TypeName="numeric";
        ТипРеквизита=  ПолучитьТипЧисла(Реквизит.Тип);

    ИначеЕсли Тип=Тип("Дата") Тогда

        ТипРеквизита=  "DateTime";


    ИначеЕсли Тип=Тип("Строка") Тогда

        КвалификаторыСтроки=Реквизит.Тип.КвалификаторыСтроки;

        ДлинаСтроки=  КвалификаторыСтроки.Длина;
        Стр=  "[StringLength("+ДлинаСтроки+")]";
        Если ДлинаСтроки=0 Тогда

            TypeName="ntext";
            Required="";
            Стр= "";
        ИначеЕсли КвалификаторыСтроки.ДопустимаяДлина=ДопустимаяДлина.Фиксированная Тогда
            TypeName="nchar";
            Required="";


        Иначе
            Required="";
            TypeName="nvarchar";
        КонецЕсли;



        ТипРеквизита=  "string";

    ИначеЕсли Тип=Тип("ХранилищеЗначения") Тогда
        TypeName= "image";
        ТипРеквизита= "byte[]";

    ИначеЕсли Тип=Тип("УникальныйИдентификатор") Тогда
        Стр=  "[MaxLength(16)]";
        ТипРеквизита= "byte[]";
    ИначеЕсли  Справочники.ТипВсеСсылки().СодержитТип(Тип) Тогда
        ИмяРеквизита=ИмяСвойства+"Id";
        стр="[MaxLength(16)]";
        ТипРеквизита= "byte[]";
        Вид=Метаданные.НайтиПоТипу(Тип).Имя;
        ТипВид=Метаданные.НайтиПоТипу(Тип).ПолноеИмя();
        СтрВиртуал="virtual public Справочник."+Вид+" "+ИмяСвойства+" { get; set; }";
        // Когда вид реквизита видом самого справочника добавим коллекцию на подчиненные элементы
        Если ТипВид=ТипВладельцаТогда
            СтрВиртуал=СтрВиртуал+"
            |[InverseProperty("""+ИмяСвойства+""")]
            |public ICollection<Справочник."+Вид+"> ПодчиненныеДля"+ИмяСвойства+" { get; set; }";

        КонецЕсли;
    ИначеЕсли  Перечисления.ТипВсеСсылки().СодержитТип(Тип) Тогда
        ИмяРеквизита=ИмяСвойства+"Id";
        стр="[MaxLength(16)]";
        ТипРеквизита= "byte[]";
        Вид=Метаданные.НайтиПоТипу(Тип).Имя;
        СтрВиртуал="virtual public Перечисление."+Вид+"Ссылка "+ИмяСвойства+" { get; set; }";

    Иначе
        // Ссылочный тип Который пока не реализован
        ИмяРеквизита=ИмяСвойства+"Id";
        ТипВид=Метаданные.НайтиПоТипу(Тип).ПолноеИмя();
        стр="[MaxLength(16)]";
        ТипРеквизита= "byte[]";
        Вид=Метаданные.НайтиПоТипу(Тип).Имя;
        //  СтрВиртуал="virtual public "+ТипВид+" "+ИмяСвойства+" { get; set; }";

    КонецЕсли;

    Если TypeName<>"" Тогда
        Стр1=  "[Column("""+ПолеБД+""",TypeName = """+TypeName+""")]";

    Иначе
        Стр1=  "[Column("""+ПолеБД+""")]";



    КонецЕсли;
    Если Стр<>""  Тогда

        Стр="
        |"+Стр;

    КонецЕсли;

    Стр=Стр1+Required+стр+"
    |public "+ТипРеквизита+" "+ИмяРеквизита+" { get; set; }";


    ТекстПолей.ДобавитьСтроку("");
    ТекстПолей.ДобавитьСтроку(Стр);
    Если СтрВиртуал<>"" Тогда

        ТекстВиртуальных.ДобавитьСтроку(СтрВиртуал);

    КонецЕсли;


КонецПроцедуры



Процедура ДобавитьВиртНеопред(ИмяСвойства,Текст)

Стр="   [NotMapped]
|public object %1 { get{return КонстантыБД.ПолучитьЗначениеНеопределенногоТипа(%1Id);} set{КонстантыБД.УстановитьЗначениеНеопределенногоТипа(value,%1Id);} }";

Текст.ДобавитьСтроку(СтрШаблон(Стр,ИмяСвойства));

КонецПроцедуры

Функция ПрописьРеквизитовПоКоллекции(ТипВладельца,Коллекция,Поля,ТекстПолей,ТекстВиртуальных,ТекстНеопределенныхТипов)
    Перем ИмяКлассаНТ;

    Для каждого Реквизит Из Коллекция Цикл
        ИмяРеквизита= Реквизит.Имя;
        ПолеБД=ПолучитьПолеБД(Поля,ИмяРеквизита);
        Сообщить("ИмяРеквизита="+ИмяРеквизита+"  ПолеБД="+ПолеБД);
        Типы=Реквизит.Тип.Типы();
        Если Типы.Количество()=1 Тогда
            Тип=Типы[0];

            ПрописатьРеквизит(тип,ИмяРеквизита,ПолеБД,Реквизит,ТекстПолей, ТекстВиртуальных,ТипВладельца)

        Иначе
            СоздатьНеопределенныйТип(ИмяРеквизита,ПолеБД,Реквизит.Тип,ТипВладельца,ТекстНеопределенныхТипов,ИмяКлассаНТ);
            ТекстПолей.ДобавитьСтроку("public НеопределенныеТипы."+ИмяКлассаНТ+" "+ИмяРеквизита+"Id { get; set; }");
             ДобавитьВиртНеопред(ИмяРеквизита,ТекстВиртуальных);


        КонецЕсли;


    КонецЦикла;


КонецФункции

 

 

 

Также добавлен класс расширения для работы с УИД 1С и byte[]

 

publicstaticclassРасширениеДляГуид

    {

        public  static  string  ВСтроку16(this  byte[] bytes)

        {

            char[] c = new  char[bytes.Length * 2];

 

            byte b;

 

            for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx)

            {

                b = ((byte)(bytes[bx] >> 4));

                c[cx] = (char)(b > 9 ? b - 10 + 'A' : b + '0');

 

                b = ((byte)(bytes[bx] & 0x0F));

                c[++cx] = (char)(b > 9 ? b - 10 + 'A' : b + '0');

            }

 

            return  new  string(c);

        }

 

        public  static  string  УИд1С(thisbyte[] ДанныеБД)

        {

            varстр = ДанныеБД.ВСтроку16();

 

            varч1 = стр.Substring(24, 8);

            varч2 = стр.Substring(20, 4);

            varч3 = стр.Substring(16, 4);

            varч4 = стр.Substring(0, 4);

            varч5 = стр.Substring(4, 12);

            return (ч1 + "-" + ч2 + "-" + ч3 + "-" + ч4 + "-" + ч5);

        }

 

        public  static  Byte[] Строка16ВМассив(this  string str)

        {

            var res = new  byte[str.Length / 2];

 

            for (int i = 0; i < res.Length; i++)

                res[i] = Convert.ToByte(str.Substring(i * 2, 2), 16);

 

            return res;

        }

        public  static  Byte[] ПолучитьМассивПоУИд(this  string UUID)

        {

            varч1 = UUID.Substring(19, 4);

            varч2 = UUID.Substring(24, 12);

            varч3 = UUID.Substring(14, 4);

            varч4 = UUID.Substring(9, 4);

            varч5 = UUID.Substring(0, 8);

            var str = ч1 + ч2 + ч3 + ч4 + ч5;

 

            return  Строка16ВМассив(str);

 

 

        }

 

 

 

 

 

    }

 

    public  static  class  Converter

    {

 

        public static byte[] ВLittleEndian(this  byte[] ДанныеИзБд)

        {

            var res = new  byte[ДанныеИзБд.Length];

 

            for (var i = 0; i < ДанныеИзБд.Length; i++)

                res[res.Length - 1 - i] = ДанныеИзБд[i];

 

            return res;

        }

        public  static  int byteArrayToInt(this  byte[] ДанныеИзБд)

        {

 

            byte[] данные;

            if (BitConverter.IsLittleEndian)

                данные = ДанныеИзБдLittleEndian();

            else

                данные = ДанныеИзБд;

 

            return  BitConverter.ToInt32(данные, 0);

        }

 

        public  static  byte[] intToByteArray(this  int  значение)

        {

 

            var res = BitConverter.GetBytes(значение);

            if (BitConverter.IsLittleEndian)

                Array.Reverse(res);

 

            return res;

        }

 

        public  static  byte ВБайт(this  byte[] ДанныеИзБд)

        {

 

            return  ДанныеИзБд[0];

        }

 

 

        public  static  byte[] БайтВмассив(this  byteданные)

        {

 

            return  new  byte[] { данные };

        }

 

        public  static  byte[] БулевоВМассив(this  boolданные)

        {

 

            return BitConverter.GetBytes(данные);

        }

 

        public  static  bool  ВБулево(this  byte[] ДанныеИзБд)

        {

 

            return  BitConverter.ToBoolean(ДанныеИзБд, 0);

        }

    }

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. WKBAPKA 226 25.09.15 09:02 Сейчас в теме
тысяча чертей! что это?
LeXXeR; dmalyshev; Silenser; michmich; Yakud3a; pbazeliuk; Andreyyy; Andrefan; ya.Avoronov; kasper076; +10 Ответить
3. RomanRomans 28.09.15 21:31 Сейчас в теме
4. Serginio 871 29.09.15 14:18 Сейчас в теме
(3) Да нет все очень прозрачно и понятно. Просто нужно уметь готовить
5. baracuda 2 06.10.15 15:30 Сейчас в теме
(4) Для описания формирования классов добавляется в проект как ссылка на публикуемый интерфейс ODATA в SERVICE REFERENCE?
6. Serginio 871 06.10.15 16:55 Сейчас в теме
Нет. Для этого в части I есть обработка которая формирует модули
http://infostart.ru/public/393228/
7. утюгчеловек 31 08.05.16 22:38 Сейчас в теме
Очень круто.

Но есть пожелание: как-нибудь формулировать в аннотации статьи решаемую задачу.
А то получается что статья про использование технологии, но ни слова о том зачем это нужно, решая какую задачу автору пришлось изучить технологию.
Я, например, нашел статью по ключевым словам. Но ведь есть и те, кто просто набрел сюда случайно.
Linq to 1C ради Linq to 1C, получается.

И кстати ни в одной из статей серии нет выводов.
8. Serginio 871 09.05.16 08:51 Сейчас в теме
Прежде всего это нужно для интеграции с другими программами. В том числе и Asp.Net. Если в 8.x есть вэб,HTTP сервисы,ODATA. То в 7 ке грустно. COM медленный. И главное это скорость выполнения и программирования
Оставьте свое сообщение

См. также

Аналог PIVOT в запросе 1С (как выполнить транспонирование таблицы в запросе 1С) Промо

Практика программирования v8 Бесплатно (free)

В статье показывается простой метод реализации аналога оператора PIVOT в запросе 1С без использования соединений.

12.12.2020    3606    Eugen-S    20    

Полезные примеры СКД, ч.2

Практика программирования v8 v8::СКД Бесплатно (free)

Еще несколько примеров решения задач в СКД.

06.04.2021    9705    Neti    8    

Неочевидные нюансы записи управляемой формы

Практика программирования v8 v8::УФ Платформа 1C v8.2 1cv8.cf Бесплатно (free)

Разберем несколько нюансов записи управляемой формы.

02.04.2021    11114    SeiOkami    52    

Обзор полезных методов БСП 3.1.4

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Бесплатно (free)

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

25.03.2021    35381    rayastar    51    

Использование классов .Net в 1С для новичков Промо

Практика программирования Разработка внешних компонент Универсальные функции v7.7 v8 Бесплатно (free)

Руководство для новичков. Написав статью http://infostart.ru/public/238584/, я понял, что многие не понимают того, что написано. Поэтому в этой статье постараюсь более подробно остановиться на азах и без кода на вражеском языке (C#)

27.01.2016    84725    Serginio    113    

Звуковое управление в 1С 8.3

Практика программирования v8 1cv8.cf Бесплатно (free)

В данной статье описано создание библиотеки для звукового управления (выполнение команд голосом) для платформы 1С 8.3. Задача была поставлена так, чтобы модуль функционировал непосредственно на клиенте 1С, осуществляя управление формами, и взаимодействовал с интерфейсом.

16.03.2021    6696    velemir    31    

Доработка проведения в ERP 2.5. (Регистры накопления, Регистры сведений)

Практика программирования v8 ERP2 БУ Бесплатно (free)

Покажу точки входа для доработки "типового" проведения документов в ERP для регистров оперативного учета. Рассмотрим три основные ситуации: нужно изменить имеющееся проведение документа; нужно сделать записи в существующие регистры; нужно с нуля описать алгоритм проведения в добавленный регистр. Пример реализован на 1С:ERP Управление предприятием 2 (2.5.4.120)

10.01.2021    9969    BuriyLesha    10    

Serverless (Faas) в 1С. Создание и вызов Yandex Cloud Functions

Универсальные функции Практика программирования v8 Бесплатно (free)

"Я не могу просто взять и скопировать код с гитхаба", "у нас 1С микросервисами окружена", "возможностей мало" - частые фразы 1С разработчиков. которым не хватает возможностей платформы в современном мире. Faas, конечно, история не новая, но нас сдерживало 152ФЗ и задержки по пингам. Для того, чтобы действительно использовать в 1С код, к примеру, на Python, надо было приложить усилия. Теперь всё намного проще - берём и используем.

28.12.2020    8379    comol    31    

Использование программных перечислений, ч.1: строковые константы Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Часто ли у вас возникает необходимость в коде выполнять сравнение на строку?

10.12.2016    40721    unichkin    74    

Базовые вещи БСП, которые облегчат жизнь программисту 1С

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Россия Бесплатно (free)

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

30.08.2020    18991    quazare    34    

Работа с журналом регистрации. Выходим за границы платформы

Журнал регистрации Бесплатно (free)

Работа с журналом регистрации нестандартными средствами. А также немного про использование платформы .NET в экосистеме 1С.

12.05.2020    10394    YPermitin    29    

Вспомогательные инструкции в коде 1С Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Помогаем редактору кода 1С помогать нам писать и анализировать код.

15.10.2018    35586    tormozit    106    

Серверные вызовы, которые нельзя вызывать

Практика программирования v8 v8::УФ 1cv8.cf Бесплатно (free)

Не баян, а классика. Рассмотрим особенность платформы настолько же древнюю, как сами УФ.

12.05.2020    8911    SeiOkami    34    

Форма выбора (подбор) в управляемых формах

Практика программирования v8 v8::УФ 1cv8.cf Россия Бесплатно (free)

Разбор небольших примеров того, как правильно открывать форму выбора (подбора) в управляемых формах, не прибегая к модальным окнам.

08.05.2020    70166    user5300    19    

Программная работа с настройками СКД

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Нюансы программной работы с настройками системы компоновки данных в отчетах и динамических списках. Обзор всех видов настроек компоновки. Что в каких случаях правильно применять. В качестве примера рассмотрена работа с отборами и группировками.

27.01.2020    61623    ids79    26    

Оформление и рефакторинг сложных логических выражений Промо

Практика программирования v8 Россия Бесплатно (free)

В сложных логических выражениях нередко самому автору спустя какое-то время тяжело разобраться, не говоря уже о других программистах. Предлагаемая методика позволяет повысить наглядность таких выражений путем оформления в виде И-ИЛИ дерева и одновременно выполнять их рефакторинг.

20.09.2012    82429    tormozit    131    

[СКД] Программное создание схемы компоновки данных

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Сделаем отчет на СКД полностью программно, без использования макета "схема компоновки данных".

15.01.2020    41655    John_d    22    

Последовательности событий при проведении документа 1С. Шпаргалка + про формы + про расширения

Практика программирования v8 Россия Бесплатно (free)

Собрал информацию о событиях/подписках/расширениях в одном месте.

30.12.2019    33285    kuzyara    38    

30 задач. Странных и не очень

Практика программирования v8 Бесплатно (free)

30 задач на знание языка программирования 1С и некоторого поведения платформы. Маленьких. Странных и не очень.

02.12.2019    23349    YPermitin    62    

Запись значения в поле ввода/формы со срабатыванием события ПриИзменении Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Иногда возникает необходимость после записи значения в какое либо поле ввода/формы вызвать для него обработчик события ПриИзменении, а о вызове самого события приходится только мечтать. В этой статье приводится программный способ вызова этого события.

11.07.2007    53788    tormozit    51    

Как передать IP адрес, который вызвал HTTP запрос в 1C (для веб-сервера Apache)

Практика программирования v8 Бесплатно (free)

Столкнулся с задачей получения IP адреса, который вызывает http сервис 1С. Итак, решение:

22.11.2019    11874    Sibars    19    

Полезные процедуры и функции для программиста

Практика программирования Универсальные функции v8 1cv8.cf Россия Бесплатно (free)

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

07.10.2019    38788    HostHost    41    

Таблица значений. Нюансы

Практика программирования v8 Бесплатно (free)

Обзор некоторых аспектов использования общеизвестного инструмента 1С.

01.10.2019    51230    Yashazz    56    

Как сделать из &НаКлиентеНаСервереБезКонтекста почти &НаКлиентеНаСервере Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Как сделать метод формы, доступный на клиенте и на сервере одновременно, и сохранить при этом удобство разработки

10.09.2017    50536    tormozit    74    

О программе Postman для тестирования API и для чего она нужна 1С-нику

Практика программирования Программное обеспечение (software) v8 Бесплатно (free)

Для чего нужна программа Postman для тестирования API и какая от него польза для 1С-программиста.

24.09.2019    19433    budidich    31    

[Шпаргалка] Программное создание элементов формы

Практика программирования Работа с интерфейсом v8 1cv8.cf Бесплатно (free)

Программное создание практически всех популярных элементов формы.

06.09.2019    95947    rpgshnik    75    

Агрегатные функции СКД, о которых мало кто знает

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Пользуетесь ли Вы всеми возможными агрегатными функциями, которые предоставляет система компоновки данных? Если Вы используете только: СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, то эта статья для Вас.

05.09.2019    74455    ids79    55    

Выгрузка документа по условию Промо

Практика программирования Разработка v8 Бесплатно (free)

Что делать, если документы нужно выгружать не все подряд, а по какому-то фильтру: статусу, дате, набору условий... А что если он соответствовал этим условиям, а потом перестал? А если потом опять начал? Такие ситуации заставили попотеть не одного программиста.

25.04.2019    17779    m-rv    3    

Регистры бухгалтерии. Общая информация

Практика программирования Математика и алгоритмы v8 v8::БУ БУ Бесплатно (free)

Общая информация о внутреннем устройстве регистров бухгалтерии.

05.09.2019    44526    YPermitin    25    

Три костыля. Сказ про фокусы в коде

Практика программирования v8 Бесплатно (free)

Три интересных (или странных) костыля в коде, которые могут помочь в повседневных и не очень задачах.

03.09.2019    29826    YPermitin    81    

Отслеживание выполнения фонового задания

Практика программирования Универсальные функции Разработка v8 1cv8.cf Бесплатно (free)

Запуск фонового задания из модуля внешней обработки. Отслеживание выполнения задания в виде прогресса, расположенного на форме.

17.08.2019    44012    ids79    22    

Как прикрутить ГУИД к регистру сведений Промо

Практика программирования Перенос данных из 1C8 в 1C8 Разработка v8 Бесплатно (free)

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

16.04.2019    23010    m-rv    18    

Функции СКД: ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Подробное описание и использование внутренних функций системы компоновки данных: Вычислить, ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив, ВычислитьВыражениеСГруппировкойТаблицаЗначений.

08.08.2019    144017    ids79    75    

Фоновое выполнение кода в 1С - это просто

Практика программирования v8 1cv8.cf Бесплатно (free)

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

02.08.2019    58223    avalakh    26    

Разбираемся с параметрами редактирования СКД

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Связь по типу, Параметры выбора, Связи параметров выбора

31.07.2019    39873    json    16    

Как сделать запрос на изменение данных Промо

Практика программирования v8 v8::Запросы 1cv8.cf Бесплатно (free)

В статье приведены особенности внутренней архитектуры и примеры работы с расширением языка запросов 1С.

01.06.2018    36229    m-rv    23    

СКД - наборы данных и связи между ними, создание собственной иерархии, вложенные отчеты

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Набор данных объект. Использование в схеме компоновки нескольких наборов данных. Различные варианты связи наборов: объединение, соединение. Использование иерархии в отчетах на СКД. Создание собственной иерархии, иерархия детальных записей. Использование вложенных схем в отчетах на СКД.

26.07.2019    101087    ids79    16    

СКД - использование расширений языка запросов, секция ХАРАКТЕРИСТИКИ

Инструментарий разработчика Практика программирования v8 v8::СКД Бесплатно (free)

Автоматическое и не автоматическое заполнение полей компоновки данных. Использование расширений языка запросов для СКД «{…}», секция ВЫБРАТЬ, секция ГДЕ, параметры виртуальных таблиц. Автоматизированное использование дополнительных данных в запросе: секция ХАРАКТЕРИСТИКИ.

17.07.2019    47189    ids79    27    

Регистры сведений. За кулисами

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

Небольшие заметки по внутреннему устройству регистров сведений.

09.07.2019    33148    YPermitin    14    

Метод формирования движений в типовых регистрах нетиповыми регистраторами Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

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

05.12.2017    30597    itriot11    34    

"Меньше копипаста!", или как Вася универсальную процедуру писал

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Программист Вася разбирает подход создания универсальных методов на примере программного вывода СКД.

04.07.2019    22271    SeiOkami    53    

Работа с настройками системы компоновки данных

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Варианты отчетов, работа с настройками вариантов: структура группировок, поля отчета, отборы, сортировка, условное оформление, другие настройки, настройки отображения диаграмм.

02.07.2019    80859    ids79    18    

Создание отчетов с помощью СКД - основные понятия и элементы

Практика программирования Математика и алгоритмы v8 v8::СКД Бесплатно (free)

Основные принципы работы СКД. Понятия схемы компоновки и макета компоновки. Описание основных элементов схемы компоновки: наборы данных, поля, вычисляемые поля, ресурсы, параметры.

25.06.2019    73713    ids79    28    

Регистры накопления. Виртуальные таблицы. Часть №2: "Остатки" и "Остатки и обороты"

Практика программирования v8 1cv8.cf Бесплатно (free)

Описание работы платформы 1С:Предприятие 8.2 с виртуальными таблицами регистров накопления "Остатки" и "Остатки и обороты". Анализ SQL-запрос при работе с виртуальными таблицами

22.05.2019    42358    YPermitin    8    

Регистры накопления. Структура хранения в базе данных

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

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

16.05.2019    61430    YPermitin    31    

О расширениях замолвите слово...

Практика программирования Разработка v8 Бесплатно (free)

О чём стоит задуматься при принятии решения о создании расширения конфигурации…

07.04.2019    41955    ellavs    131    

Git-репозитории для 1С-кода (опыт использования при небольших проектах)

Практика программирования v8 Бесплатно (free)

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

28.03.2019    31586    ellavs    90