Здравствуйте

Задача:

Необходимо создать User Task, в которой создать объект ICompositeObjectList и для последующей передачи значения в другую User Task.

 

Данный пример не работает:

1 SoureCode:

namespace JustTestCompositeObject
{
    using System;
    using System.Collections.Generic;
    using Terrasoft.Common;
    public class A : ICompositeObject
    {
        internal string test;
        public bool TryGetValue(string key, Type valuetype, out object value) { value = default; return true; }
        public bool TryGetValue<TValueType>(string key, out TValueType value) { value = default; return true; }
    }
    public class TestCompositeObjectList : List<A>, ICompositeObjectList<A>
    {
        void ISerializableObject.Serialize(DataWriter dataWriter) { }
        void ISerializableObject.Deserialize(DataReader dataReader) { }
    }
    public class test
    {
        public static ICompositeObjectList<ICompositeObject> GnerateTestList()
        {
            TestCompositeObjectList list = new TestCompositeObjectList();
            list.Add(new A { test = "test1" });
            list.Add(new A { test = "test2" });
            return list;
        }
 
        public static string PrintTest(ICompositeObjectList<ICompositeObject> list)
        {
            string output = "";
            if (list == null)
            {
                output = "this collection is null";
            }
 
            foreach (A v in list)
            {
                output += v.test + " ";
            }
            return output;
        }
    }
}

UserTask1:

list = test.GnerateTestList();
return true;

, где list задан как тип: Serializable list of composite values

 

UserTask2:

output=test.PrintTest(list);
return true;

, где list имеет тип: Serializable list of composite values; output имеет тип: string

 

Процесс выглядит вот так:

Изображение удалено.

На Auto-generated page выводится output из UserTask2 

Конфигурация успешно компилируется.

 

Пробовал прописывать Usings на необходимый namespace в свойствах процесса, не работает...

 

Вещи типа: 

Изображение удалено.

не работают и не возвращаются значение

 

В Visual Studio все ок работает в конфигурации при передачи значений через процесс - нет.

 

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

 

Пожалуйста подскажите как можно решить подобную задачу.

Нравится

1 комментарий

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

А сейчас скрипты работают автономно и обмениваются значениями с параметрами через Get и Set.

Get&lt;T&gt;(string path)
Set(string path, T value)

Получится ли таким образом передать объект ICompositeObjectList, нужно экспериментировать, а по поводу возможности существования внутри БП класса с вызовом статических методов, сомневаюсь.

 

Больше об этом можно почитать тут и тут, а также тут и тут.

Показать все комментарии

Добрый день. Элемент БП "Читать данные", в случае чтения коллекции, на выходе отдаёт параметр ICompositeObjectList ResultCompositeObjectList. Необходимо создать элемент процесса, который будет производить конвертацию этого параметра обратно в EntityCollection, с целью получения Entity, в которой будет содержатся данные об одном элементе из коллекции. И дальнейшей передачи этой Entity в следующий элемент процесса. Каким образом это можно сделать?

Нравится

6 комментариев

См. обсуждение аналогичного вопроса тут.

Зверев Александр,

Я находил данное обсуждение, спасибо, но там, к сожалению нет решения моей проблемы. Напомню, мне нужен элемент бизнес-процесса, у которого в выходном параметре будет содержаться один элемент из коллекции. А как этот выходной параметр создать? В идеале этот параметр должен быть с типом "CompositeObject", но дело в том, что параметр в элементе процесса можно создавать только из предложенных типов (строка, entity, число и т.д.) и среди этих вариантов нет типа: "CompositeObject".

Можно создать параметр процесса типа Entity или EntityCollection и программно его наполнять значением при помощи элемента-скрипта с кодом, как по ссылке.

Зверев Александр,

Не могли бы Вы привести в пример код, о котором Вы говорите? Тот код что по ссылке в foreach перебирает элементы коллекции с типом CompositeObjectList и передаёт элемент из этой коллекции в элемент с типом CompositeObject.

Я про это действие: 

foreach(var entity in entities)

для entity хоть и используется неявная типизация, но в процессе отладки удалось установить, что для entity назначается тип CompositeObject.

Мне кажется, проще будет вообще не использовать элемент чтения в БП, пытаясь потом вытянуть из него в нужном формате, а всё сделать чисто программно в блоке-скрипте, используя механизмы Select или EntitySchemaQuery, в зависимости от потребностей.

Зверев Александр,

Спасибо за помощь.

Показать все комментарии

Здравствуйте, коллеги!

Сделал велосипед - перебор результирующей коллекции > элемента БП "Чтение данных" и решил поделиться для "будущих поколений".

Тестовый БП:

Изображение удалено.

читаем счета

Изображение удалено.

 

в Методах БП объявляем переменную, в которой будем хранить коллекцию, в данном случае invoices и методы доступа к колонкам объекта GetCompositeObjectColumnValue и перехода на следующую запись коллекции CompositeObjectListMoveNext

Изображение удалено.

инициализируем переменную коллекции

Изображение удалено.

Перебираем коллекцию и читаем поля текущей записи коллекции

Изображение удалено.

Готово!

Нравится

Поделиться

10 комментариев

Какие тэги поставить, что бы в топе выдачи поиска по теме было?

Борис Леонов,

а как обойти это ограничение?

Миннекаев Айдар,

я не знаю, пробовал 5000 - позволяет

Для статей при создании поста можно выбрать тип «Публикация» вместо «Вопрос».

По сути темы, таких масштабных чтений лучше избегать, ведь это требует большого объёма памяти как на сервере БД, так и на веб-сервере. Если действительно нужно обработать так много записей, лучше порциями.

Зверев Александр,

Точно! Поменял на публикацию. А теги какие добавить? Идея то востребованная, куча вопросов на эту тему...

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

Как на Хабре, тег #никто_не_читает_теги.cheeky

Можно читать первые N штук, а потом каждую обрабатывать, чтобы не попадали под условия выборки, затем читать очередные N штук. А если записи не меняются, то непонятно, зачем так много читать, а не фильтровать ещё на уровне запроса в базу.

 

Борис, Спасибо!

Очень помогли.

И как жаль, что до сих пор нет базового инструмента для работы с коллекциями и способа перевода в EntityCollection

 

 Это же каким извращенцем нужно быть, чтоб кусок кода давать в виде скриншота) что ж вы за люди))))))

Stradivarius,

я посчитал, что он читается лучше, потому что вставленное как <код> тут выглядит ужасно

 Methods

private IEnumerator&lt;ICompositeObject&gt; entities;
 
private T GetCompositeObjectColumnValue&lt;T&gt;(IEnumerator&lt;ICompositeObject&gt; objectList, string columnName) {
		ICompositeObject currentObject = objectList.Current;
		if(currentObject != null) {
			currentObject.TryGetValue&lt;T&gt;(columnName, out T value);
			return value;
		} else {
			return default(T);
		}
 
}
 
private bool CompositeObjectListMoveNext(IEnumerator&lt;ICompositeObject&gt; objectList) {
	return objectList.MoveNext();
}

Init

entities = Get&lt;ICompositeObjectList&lt;ICompositeObject&gt;&gt;("ReadDataUserTask1.ResultCompositeObjectList").GetEnumerator();
return true;

Processing

Set("MoveNext", CompositeObjectListMoveNext(entities));
string name = GetCompositeObjectColumnValue&lt;string&gt;(entities, "Name");
// Работает с Name
return true;

 

Показать все комментарии