Связать метод

Я пытаюсь связать связанные записи объекта с вновь созданным. Плагин срабатывает при создании и предварительной работе.

Ошибка возникает при попытке связать коллекцию с новым объектом: «new_ligneContrat With Id = ad630ba6-684e-e111-92e3-00155d151905 не существует»

Вот мой код:

public void Execute(IServiceProvider serviceProvider)
        {
            // Instanciation des services

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = factory.CreateOrganizationService(null);


            Entity target = (Entity)context.InputParameters["Target"];
            EntityReference contrats = (EntityReference)target.Attributes["new_contratsid"];

            FetchExpression fetch = new FetchExpression(@"
                    <fetch distinct='false' mapping='logical'>
                      <entity name='" + context.PrimaryEntityName + "'><link-entity name='new_contrats' alias='nombreligne' from='new_contratsid' to='new_contratsid'><filter type='and'><condition attribute='new_contratsid' value='" + contrats.Id + "' operator='eq'></condition></filter></link-entity></entity></fetch>");

            EntityCollection lines = service.RetrieveMultiple(fetch);

                  // Vérification qu'il y a au moins une ligne de contrat associée
            if (lines.Entities.Any())
            {

                var first = lines.Entities.Last();

                if (first.GetAttributeValue<OptionSetValue>("statecode").Value == 1)
                {
                    FetchExpression query = new FetchExpression(@"
                        <fetch distinct='false' mapping='logical'>
                        <entity name='incident'><filter type='and'><condition attribute='new_lignecontrat' value='"+first.Id+"' operator='eq'/></filter></entity></fetch>");

                    EntityCollection incident = service.RetrieveMultiple(query);

                    if (incident.Entities.Any())
                    {


                        foreach (var e in incident.Entities)
                        {
                           e.Attributes["new_lignecontrat"] = new EntityReference (target.LogicalName, target.Id);
                        }


                 }
              }
           }   

Что случилось???

Заранее спасибо!!

Редактировать 1: ok кажется логичным, поскольку запись еще не существует >‹. Только одно: как я могу изменить значение поля поиска? Каков его тип?

Редактировать 2: у меня нет ошибки при выполнении моего кода, но поля объекта инцидента не обновляются >‹'.... Я проверил свой код с invalidPluginExceptions, и конец кода достигнут... Здесь это код:

Редактировать 3: код обновлен...


person MademoiselleLenore    schedule 03.02.2012    source источник


Ответы (1)


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

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

Таким образом, для обработки ассоциации вы можете либо изменить стадию на послеоперационную, либо один класс IPlugin будет обрабатывать предоперационную стадию, а другой — послеоперационную стадию в одном или нескольких проектах.

Чтобы ответить на редактирование, поля поиска относятся к классу EntityReference. (Похоже, вы работаете с отношениями 1:N?)

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

if (entity.Attributes.ContainsKey("new_lignecontrat"))
{
    entity.Attributes["new_lignecontrat"] = YourEntityReference;
}
else //attribute not included in the plugin operation
{
    entity.Attributes.Add("new_lignecontrat", YourEntityReference);
}

У Microsoft есть демонстрация этой концепции в SDK:

\sdk\samplecode\cs\plug-ins\accountnumberplugin.cs

person Peter Majeed    schedule 03.02.2012
comment
Спасибо за экскурсионный ответ Петр! Запуск плагинов после операции не проблема. Я действительно работаю над отношениями 1:N. На самом деле мне нужно, чтобы при создании нового new_lignecontrat обновлялось поле поиска, связанное с предыдущим в объекте инцидента. То же самое можно сказать и о простом e.Attributes.getValue‹EntityReference›(new_lignecontrat)= new EntityReference (target.logicalName,target.Id); сделать работу? - person MademoiselleLenore; 05.02.2012
comment
@MademoiselleLenore: Верно. Вы должны использовать метод Associate для отношений N:N, но для отношений 1:N у вас есть возможность напрямую назначить EntityReference сущности, так что это будет работать нормально. - person Peter Majeed; 06.02.2012
comment
Еще раз спасибо Петр, до сих пор безрезультатно. Я отредактировал весь код. - person MademoiselleLenore; 06.02.2012
comment
@MademoiselleLenore: я думаю, что просмотр вашего кода и обнаружение проблемы могут выходить за рамки этого вопроса (хотя у меня есть некоторые мысли - например, создан ли экземпляр e.Attributes["new_lignecontrat"]?). Я могу добавить только два предложения: попробуйте отладку и попробуйте использовать < href="http://msdn.microsoft.com/en-us/library/gg327844.aspx" rel="nofollow noreferrer">с ранним связыванием вместо классов с поздним связыванием, который заботится о любых создание экземпляра атрибута для вас. - person Peter Majeed; 08.02.2012
comment
@MademoiselleLenore: Некоторая задержка! Но рад, что теперь работает. :) - person Peter Majeed; 14.02.2012