Вопрос

Получение значений в событийном слое после base.OnSaved()

Для реализации логики в событийном слове после вызова base.onSaved() в entity отсутствуют значения, которые устанавливаются в тех самых процессах объекта Saved.

Пока сделали дополнительный Select для получения обновленного entity и Update.

 

Эта верная логика или можно получить обновленный entity (полученный после отработки base.onSaved()) на событийном слое без вызова Select?

Нравится

12 комментариев
Лучший ответ

Полозюков Евгений Петрович пишет:

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

Например, если реализовывать логику интеграции со сторонним приложением в dll, то удобнее обработку событий объекта выносить в событийный слой, а не делать все в подпроцессе.

Добрый вечер.

Получить обновленный entity можно таким образом:

public override void OnSaved(object sender, EntityAfterEventArgs e)
{
   base.OnSaved(sender, e);
   Entity entity = (Entity)sender;
   var userConnection = entity.UserConnection;
  // реализуем нужную логику
 }

Ещё посмотрите вот эту статью на Академии: https://academy.terrasoft.ua/docs/developer/back-end_development/entity…

Алла Савельева,

именно так и делали по этой статье. Простой пример, который должен был показать значение Code

 

[EntityEventListener(SchemaName = "Account")] 
public class UsrAccountEntityEventListener : BaseEntityEventListener
 {
  public override void OnSaved(object sender, EntityAfterEventArgs e) {
    base.OnSaved(sender, e);
 
    var entity = (Entity) sender;
    var userConnection = entity.UserConnection;
 
    string accountCode = entity.GetTypedColumnValue<string>("Code");
 
    throw new Exception(entity.Schema.Name + " " + accountCode);

Однако значение Code, которое генерируется в процессе объекта onSaved было пустое.



Добавили Select, получили значение.

 

public override void OnSaved(object sender, EntityAfterEventArgs e) {
 base.OnSaved(sender, e);
 
 var entity = (Entity) sender;
 var userConnection = entity.UserConnection;
 Guid id = entity.PrimaryColumnValue;
 string schemaName = entity.Schema.Name;
 
 Select select = new Select(userConnection).Top(1)
  .Column("Code")
  .From(schemaName)
  .Where("Id").IsEqual(Column.Parameter(id)) as Select;
 string accountCode = select.ExecuteScalar<string>();

 

Владимир Соколов,

А зачем вам асинхронный вариант?

Обычный событийный подпроцесс нормально работает.

В ScriptTask получаем Entity.GetTypedColumnValue<string>("Code")

 

Полозюков Евгений Петрович пишет:

А зачем вам асинхронный вариант?

в каком месте у нас асинхронный вариант? 

Как раз в процессе получается асинхронно - иногда раньше, иногда позже процесса из родительского объекта

Владимир Соколов,

Мне показалось что это асинхронный вариант.

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

Полозюков Евгений Петрович,

потому что событийные подпроцессы как раз работают асинхронно

Скорее всего, из-за того, что в процессе значение для поля 'Code' устанавливается на onSaved, оно не попадает в параметр sender в обработчике в событийном слое.

 

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

Насчет того действительно ли это является ошибкой, могут ответить только в поддержке.

 

Как вариант решения, можно либо устаналивать значение для поля 'Code' не в обработчике onSaved, а в onSaving в подпроцессе объекта, либо реализовать всю логику в одном месте или в подпроцессе, или в событийном слое.

Полозюков Евгений Петрович пишет:

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

Например, если реализовывать логику интеграции со сторонним приложением в dll, то удобнее обработку событий объекта выносить в событийный слой, а не делать все в подпроцессе.

Алла Савельева пишет:

Как вариант решения, можно либо устаналивать значение для поля 'Code' не в обработчике onSaved, а в onSaving в подпроцессе объекта, либо реализовать всю логику в одном месте или в подпроцессе, или в событийном слое.

А есть идеи, как "выпилить" из базового функционала генерацию Code, оставив при этом остальные обработки процесса (синхронизация средств связи и прочее)?

Владимир Соколов,

Создайте свое поле и пишите к нему свою логику.

Владимир Соколов,

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

Алла Савельева пишет:

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

Это всё понятно. Иногда незамещаемый базовый функционал доставляет больше проблем, чем его гипотетическое отсутствие.



Workaround мы нашли, но хотелось бы понять, как было задумано в системе

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