AXForum  
Вернуться   AXForum > Microsoft Dynamics CRM > Dynamics CRM: Разработка
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 13.03.2013, 10:55   #1  
probka is offline
probka
Участник
Аватар для probka
 
98 / 11 (1) +
Регистрация: 20.02.2012
Адрес: Ростов-на-Дону
CRM 4.0 Выполнение плагина
Добрый день!
Есть плагин, который выполняется после создания экземпляра кастомной сущности new_grmember, у которой есть атрибут new_groupid. При запуске двух параллельных процессов создания двух различных экземпляров этой сущности с двух разных компьютеров одновременно в алгоритме плагина, запущенного для первого экземпляра, почему-то появляется значение new_groupid из PostImage второго экземпляра. Почему такое может быть? Это какой-то баг или ошибка алгоритма? Текст алгоритма привожу ниже.

X++:
Guid groupId = ((Lookup)GetEntityProperty("new_groupid")).Value;

//------------------//

       protected object GetEntityProperty(string propertyName)
        {
            if (_currentContext.Stage == MessageProcessingStage.AfterMainOperationOutsideTransaction)
            {
                if (_postEntityImage == null)
                    _postEntityImage = GetPostEntityImage(_currentContext, TargetEntity.Name);

                if (_postEntityImage == null)
                {
                    if (_entity.Properties.Contains(propertyName))
                    {
                        return _entity[propertyName];
                    }


                }
                else if (_postEntityImage.Properties.Contains(propertyName))
                {
                    return _postEntityImage[propertyName];
                }

                return null;
            }

            else // (_currentContext.Stage == MessageProcessingStage.BeforeMainOperationOutsideTransaction)
            {
                if (!_entity.Properties.Contains(propertyName))
                {
                    if (_preEntityImage == null)
                        _preEntityImage = GetPreEntityImage(_currentContext, TargetEntity.Name);

                    if (_preEntityImage == null)
                        return null;

                    else if (_preEntityImage.Properties.Contains(propertyName))
                    {
                        return _preEntityImage[propertyName];
                    }

                    return null;

                }

                return _entity[propertyName];
            }
            
        }

        protected static DynamicEntity GetPostEntityImage(IPluginExecutionContext _currentContext, string _EntityName)
        {
            DynamicEntity postImageEntity = null;

            if (_currentContext.PostEntityImages.Contains(_EntityName))
                postImageEntity = _currentContext.PostEntityImages[_EntityName] as DynamicEntity;

            return postImageEntity;
        }
__________________
Так победим!

Старый 13.03.2013, 13:51   #2  
a33ik is offline
a33ik
Чайный пьяница
Аватар для a33ik
MCP
MCBMSS
Злыдни
Соотечественники
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,243 / 896 (36) +++++++
Регистрация: 02.07.2008
Адрес: Greenville, SC
Покажите пожалуйста кусок кода плагина, где вы объявляете _currentContext, где присваиваете значение.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством.

Подписывайтесь на мой блог, twitter и YouTube канал.
Пользуйтесь моим Ultimate Workflow Toolkit

Последний раз редактировалось a33ik; 13.03.2013 в 13:51. Причина: Туплю. 4.0 - какая нафиг изоляция.
Старый 13.03.2013, 13:55   #3  
probka is offline
probka
Участник
Аватар для probka
 
98 / 11 (1) +
Регистрация: 20.02.2012
Адрес: Ростов-на-Дону
Цитата:
Сообщение от a33ik Посмотреть сообщение
Покажите пожалуйста кусок кода плагина, где вы объявляете _currentContext, где присваиваете значение.
X++:
public abstract class PluginBase : IPlugin
    {
        protected DynamicEntity _preEntityImage = null;
        protected DynamicEntity _entity = null;
        protected Moniker _moniker = null;
        protected DynamicEntity _postEntityImage = null;

        protected string _secureInformation;
        protected string _unsecureInformation;
        protected IPluginExecutionContext _currentContext;

        public PluginBase(string unsecureInfo, string secureInfo)
        {
            _unsecureInformation = unsecureInfo;
            _secureInformation = secureInfo;

        }

        public virtual void Execute(IPluginExecutionContext context)
        {
            _currentContext = context;

        }

    }
__________________
Так победим!

Старый 13.03.2013, 14:29   #4  
g.Naukovych is offline
g.Naukovych
Участник
MCBMSS
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
405 / 130 (5) +++++
Регистрация: 23.03.2011
protected DynamicEntity _preEntityImage = null;
protected DynamicEntity _entity = null;
protected Moniker _moniker = null;
protected DynamicEntity _postEntityImage = null;

protected IPluginExecutionContext _currentContext;

вот этот код необходимо внести в метод Execute

из-за этого и проблема.
__________________
Мой блог https://procrm.tv
За это сообщение автора поблагодарили: probka (1).
Старый 13.03.2013, 14:33   #5  
probka is offline
probka
Участник
Аватар для probka
 
98 / 11 (1) +
Регистрация: 20.02.2012
Адрес: Ростов-на-Дону
Цитата:
Сообщение от g.Naukovych Посмотреть сообщение
protected DynamicEntity _preEntityImage = null;
protected DynamicEntity _entity = null;
protected Moniker _moniker = null;
protected DynamicEntity _postEntityImage = null;

protected IPluginExecutionContext _currentContext;

вот этот код необходимо внести в метод Execute

из-за этого и проблема.
Но это переменные, которые должны быть доступны вне метода Execute. Если я внесу их, разве не нарушится область видимости? И как это связано с моей проблемой?
__________________
Так победим!

Старый 13.03.2013, 14:41   #6  
a33ik is offline
a33ik
Чайный пьяница
Аватар для a33ik
MCP
MCBMSS
Злыдни
Соотечественники
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,243 / 896 (36) +++++++
Регистрация: 02.07.2008
Адрес: Greenville, SC
Цитата:
Сообщение от probka Посмотреть сообщение
Но это переменные, которые должны быть доступны вне метода Execute. Если я внесу их, разве не нарушится область видимости? И как это связано с моей проблемой?
С вашей проблемой это связано напрямую. Механика плагинов в 4.0 следующая - инстанциируется только один инстанс класса плагина, соответственно все переменные класса - общие для всех запусков, именно поэтому у вас и происходит это перекрывание значений. Переписывайте.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством.

Подписывайтесь на мой блог, twitter и YouTube канал.
Пользуйтесь моим Ultimate Workflow Toolkit
За это сообщение автора поблагодарили: probka (1).
Старый 13.03.2013, 18:01   #7  
probka is offline
probka
Участник
Аватар для probka
 
98 / 11 (1) +
Регистрация: 20.02.2012
Адрес: Ростов-на-Дону
Переписала. Не помогло. Скидываю полный текст плагина, может быть, кто подскажет, что я сделала не так.

X++:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Win32;

using Softline.MsCrm40.Sdk;
using Softline.MsCrm40;

using Softline.Runov.Apps.Plugins_new.DataAccess;


namespace Softline.Runov.Apps.Plugins_new
{
    public class PostCreateGroupMember : Plugin
    {
        public PostCreateGroupMember(string unsecureInfo, string secureInfo)
            : base(unsecureInfo, secureInfo)
        {
        }

        public override void Execute(IPluginExecutionContext context)
        {
             try
            {

                if (PluginConfiguration.LogIncomingMessages)
                {
                    Logger.WriteInfo("PostCreateGroupMember Plug-in running.\nPluginExecutionContext:\n" + PluginHelper.GetContextXml(context));
                }

                if (context.CallerOrigin is OfflineOrigin)
                    return;

                DynamicEntity TargetEntityLocal = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];
                if (context.MessageName == "Create" && TargetEntityLocal.Properties.Contains("new_groupid"))
                {
                    CreateVisits(context);
                 }

                UpdateGroupData(context);

            }
            catch (Exception ex)
            {
                StringBuilder errorMessage = new StringBuilder();

                errorMessage.AppendFormat("Plug-in {0} failed\n", this.GetType().ToString());

                errorMessage.AppendFormat("PrimaryEntityName: {0}\n", context.PrimaryEntityName);
                errorMessage.AppendFormat("MessageName: {0}\n", context.MessageName);
                errorMessage.AppendFormat("Error: {0}\n", ex.Message);

                InvalidPluginExecutionException invalidPluginExecutionException = new InvalidPluginExecutionException(errorMessage.ToString(), ex);

                invalidPluginExecutionException.Data.Add("PluginExecutionContext", PluginHelper.GetContextXml(context));

                Logger.WriteError(invalidPluginExecutionException);
 
                throw invalidPluginExecutionException;

            }
            finally
            {
                Finally();
            }

        }

        private void UpdateGroupData(IPluginExecutionContext context)
        {
            CrmData crmData = new CrmData(context);
            GroupMember groupMember = new GroupMember(context);
            crmData.UpdateGroupData(groupMember.PostGroupId);
        }

        /// <summary>
        /// Создание посещений при добавлении нового обучающегося в группу
        /// </summary>
        private void CreateVisits(IPluginExecutionContext context)
        {

            Guid groupId = ((Lookup)GetEntityPropertyLocal(context, "new_groupid")).Value;

            DynamicEntity[] lessons = GroupsDataAccess.RetrieveLessonsByGroup(CrmService, groupId, "new_name", "new_groupid");

            DynamicEntity contract = CrmService.RetrieveDynamic("opportunity", ((Lookup)GetEntityPropertyLocal(context, "new_contractid")).Value, "new_numfirstles");

            int firstlesson = 0;

            if (contract.Properties.Contains("new_numfirstles"))
            {
                firstlesson = ((CrmNumber)contract["new_numfirstles"]).Value;
            }

            Guid GroupMemberIdLocal = (Guid)context.OutputParameters.Properties[ParameterName.Id];
            foreach (DynamicEntity lesson in lessons)
            {
                string lessonname = lesson["new_name"].ToString();

                if (int.Parse(lessonname) >= firstlesson)
                {
                    VisitsDataAccess.CreateVisit(CrmService, lessonname, ((Key)lesson["new_lessonsid"]).Value, GroupMemberIdLocal);
                }

            }

        }


        protected object GetEntityPropertyLocal(IPluginExecutionContext context, string propertyName)
        {
            DynamicEntity TargetEntityLocal = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];

            if (context.Stage == MessageProcessingStage.AfterMainOperationOutsideTransaction)
            {
                DynamicEntity _postEntityImageLocal = GetPostEntityImageLocal(context, TargetEntityLocal.Name);

                if (_postEntityImageLocal == null)
                {
                    if (TargetEntityLocal.Properties.Contains(propertyName))
                    {
                        return TargetEntityLocal[propertyName];
                    }


                }
                else if (_postEntityImageLocal.Properties.Contains(propertyName))
                {
                    return _postEntityImageLocal[propertyName];
                }

                return null;
            }

            else // (_currentContext.Stage == MessageProcessingStage.BeforeMainOperationOutsideTransaction)
            {
                if (!TargetEntityLocal.Properties.Contains(propertyName))
                {
                    DynamicEntity _preEntityImageLocal = GetPreEntityImageLocal(context, TargetEntityLocal.Name);

                    if (_preEntityImageLocal == null)
                        return null;

                    else if (_preEntityImageLocal.Properties.Contains(propertyName))
                    {
                        return _preEntityImageLocal[propertyName];
                    }

                    return null;

                }

                return TargetEntityLocal[propertyName];
            }

        }

        protected static DynamicEntity GetPreEntityImageLocal(IPluginExecutionContext context, string _EntityName)
        {
            DynamicEntity preImageEntity = null;

            if (context.PreEntityImages.Contains(_EntityName))
                preImageEntity = context.PreEntityImages[_EntityName] as DynamicEntity;

            return preImageEntity;
        }


        protected static DynamicEntity GetPostEntityImageLocal(IPluginExecutionContext context, string _EntityName)
        {
            DynamicEntity postImageEntity = null;

            if (context.PostEntityImages.Contains(_EntityName))
                postImageEntity = context.PostEntityImages[_EntityName] as DynamicEntity;

            return postImageEntity;
        }

   
    }
}
__________________
Так победим!

Старый 14.03.2013, 11:07   #8  
probka is offline
probka
Участник
Аватар для probka
 
98 / 11 (1) +
Регистрация: 20.02.2012
Адрес: Ростов-на-Дону
Как видно из листинга в предыдущем посте, у меня не осталось переменных класса. context определяется при запуске плагина в процедуре Execute. И все равно срабатывает так, как я описала в начале. Подскажите, это не может быть баг CRM?
__________________
Так победим!

Старый 14.03.2013, 16:44   #9  
probka is offline
probka
Участник
Аватар для probka
 
98 / 11 (1) +
Регистрация: 20.02.2012
Адрес: Ростов-на-Дону
Проблема решилась полной перерегистрацией плагина и перезапуском IIS. Спасибо за помощь еще раз.
__________________
Так победим!

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 12 Blog bot Dynamics CRM: Blogs 0 30.01.2013 01:11
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 10 Blog bot Dynamics CRM: Blogs 0 17.08.2012 03:27
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 7 Blog bot Dynamics CRM: Blogs 0 27.03.2012 02:11
crminthefield: Podcast and Overview: Microsoft Dynamics CRM 2011 Update Rollup 4 Blog bot Dynamics CRM: Blogs 0 24.09.2011 01:16
CRM DE LA CREME! Configuring Microsoft Dynamics CRM 4.0 for Internet-facing deployment Blog bot Dynamics CRM: Blogs 0 18.08.2009 11:05

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 15:10.