none
Обновление поля в связанной сущности RRS feed

  • Вопрос

  • Эсть две пользовательские сущности, которые связанные один ко многим. Вопрос следующего характера: необходимо при обновлении поля в дочерней сущности нужно обновить поле (PickList) в главной сущности.
    Например, есть список категорий ($, $$, $$$) в главной сущности и есть связанная сущность с полем площадей.
    Если мы обновляем площадь с 100 до 200 то автоматически категория в главной сущности изменяется на $$
    20 июля 2009 г. 7:25

Ответы

  • Добрый день.

    Попробуйте следующий код:

    using System;
    
    using System.Collections.Generic;
    
    using Microsoft.Win32;
    
    using Microsoft.Crm.Sdk;
    
    using Microsoft.Crm.SdkTypeProxy;
    
    using Microsoft.Crm.SdkTypeProxy.Metadata;
    
    using Microsoft.Crm.Sdk.Query;
    
    using System.Web.Services.Protocols;
    
    
    
    namespace Crm.Plugins
    
    {
    
        public class ClientAutoCategory : IPlugin
    
        {
    
            public void Execute(IPluginExecutionContext context)
    
            {
    
                try
    
                {
    
                    if (context.InputParameters.Properties.Contains(ParameterName.Target) &&
    
                    context.InputParameters.Properties[ParameterName.Target] is DynamicEntity)
    
                    {
    
                        DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];
    
                        if (entity.Name == "new_sowing" && entity.Properties.Contains("new_squre"))
    
                        {
    
                            int square = ((CrmNumber)entity.Properties["new_squre"]).Value;
    
                            int targetvalue = 0;
    
    
    
                            if (square <= 10000)
    
                                targetvalue = 1;
    
                            else if (square <= 50000)
    
                                targetvalue = 2;
    
                            else
    
                                targetvalue = 3;
    
    
    
                            Guid parententityid = ((Lookup)((DynamicEntity)context.PreEntityImages["PreUpdate"])["new_clientid"]).Value;
    
    
    
                            ICrmService service = context.CreateCrmService(true);
    
    
    
                            DynamicEntity parententity = new DynamicEntity("new_client");
    
                            parententity["new_clientid"] = new Key(parententityid);
    
                            parententity["new_category"] = new Picklist(targetvalue);
    
                            service.Update(parententity);
    
                        }
    
                    }
    
                }
    
                catch (SoapException exc)
    
                {
    
                    throw new Exception(exc.Detail.InnerText);
    
                }
    
            }
    
        }
    
    
    
    }
    
    
    
    
    При регистрации плагина Вам потребуется зарегистрировать Image c именем PreUpdate - это потребуется для получения идентификатора родительского объекта, потому как при обновлении только в случае изменения этого поля - значение будет в контексте плагина.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    Спасибо огромное, работает. Последний вопросик. Допустим в дочернем несколько записей с площадями. Они все по разным годам. Например,
    2008 - 10000
    2009 - 20000
    Мне необходимо изменять в главной сущности категорию только по последнему году сверять.
    • Помечено в качестве ответа Sergii BielskyiMVP 20 июля 2009 г. 11:27
    20 июля 2009 г. 10:53
  • Добрый день.

    Благодарность выражается нажатием под ответом кнопки пометить как ответ и нажатиями на Проголосовать за сообщение как полезное ) Этого вполне достаточно. По поводу откуда я знаю - скачал SDK и почитал. И всем рекомендую. Описание короткое, но достаточное для осмысления.
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    • Помечено в качестве ответа Sergii BielskyiMVP 20 июля 2009 г. 11:27
    20 июля 2009 г. 11:26

Все ответы

  • Добрый день.

    Лучший выход для решения Вашей задачи - написание плагина на обновление дочерней сущности. В интернете можно найти много примеров создания плагинов с детальным описанием. Например - http://ms-dynamics-crm.com.ua/2009/03/10/plug-in-ms-crm-4/
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    20 июля 2009 г. 8:06
  • Добрый день.

    Лучший выход для решения Вашей задачи - написание плагина на обновление дочерней сущности. В интернете можно найти много примеров создания плагинов с детальным описанием. Например - http://ms-dynamics-crm.com.ua/2009/03/10/plug-in-ms-crm-4/
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    Вот именно я так и думал. Даже начал писать. Но у меня не получается. Может примерчик такого рода дадите.
    20 июля 2009 г. 8:08
  • Добрый день.

    Думаю, что в данном случае лучше начать с того, что Вы уже написали и на примере - получить готовое решение.

    Приведите, пожалуйста, Ваш код, который не заработал.
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    20 июля 2009 г. 8:10
  • Добрый день.

    Думаю, что в данном случае лучше начать с того, что Вы уже написали и на примере - получить готовое решение.

    Приведите, пожалуйста, Ваш код, который не заработал.
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    Я просто не понимаю. Вот

    using

     

    System;

    using

     

    System.Collections.Generic;

    using

     

    Microsoft.Win32;

    // Microsoft Dynamics CRM namespaces

    using

     

    Microsoft.Crm.Sdk;

    using

     

    Microsoft.Crm.SdkTypeProxy;

    using

     

    Microsoft.Crm.SdkTypeProxy.Metadata;

    using

     

    Microsoft.Crm.Sdk.Query;

    namespace

     

    Crm.Plugins

    {

     

    public class ClientAutoCategory : IPlugin

    {

     

    public void Execute(IPluginExecutionContext context)

    {

     

    if (context.InputParameters.Properties.Contains(ParameterName.Target) &&

    context.InputParameters.Properties[

    ParameterName.Target] is DynamicEntity)

    {

     

    DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];

     

    if (entity.Name == "new_sowing")

    {

     

    ICrmService service = context.CreateCrmService(false);

     

     

    Picklist pick = new Picklist();

    pick.Value = CategoryPick(service, ((

    Key)(((DynamicEntity)entity)["new_clientid"])).Value);

     

    //PicklistProperty propPick = new PicklistProperty(PicklistProperty("new_"

     

    }

    }

     

    else

    {

     

    return;

    }

    }

     

    private int CategoryPick(ICrmService service, Guid key)

    {

     

    int nextNumber = 1;

     

    ColumnSet cols = new ColumnSet();

    cols.AddColumns(

    new string[] { "new_clientid", "new_category" });

     

    PagingInfo pages = new PagingInfo();

    pages.PageNumber = 1;

    pages.Count = 1;

     

    QueryExpression query = new QueryExpression();

    query.EntityName =

    "new_client";

    query.ColumnSet = cols;

    query.AddOrder(

    "new_category", OrderType.Descending);

    query.PageInfo = pages;

     

    RetrieveMultipleRequest request = new RetrieveMultipleRequest();

    request.ReturnDynamicEntities =

    true;

    request.Query = query;

     

    RetrieveMultipleResponse retrieved = (RetrieveMultipleResponse)service.Execute(request);

     

    BusinessEntityCollection entities = retrieved.BusinessEntityCollection;

     

    foreach (BusinessEntity busEntity in entities.BusinessEntities)

    {

     

    if (((Key)(((DynamicEntity)busEntity)["new_clientid"])).Value == key)

    nextNumber = 3;

    }

     

     

    if (retrieved.BusinessEntityCollection.BusinessEntities.Count > 0)

    {

     

    DynamicEntity results = (DynamicEntity)retrieved.BusinessEntityCollection.BusinessEntities[0];

     

    if (results.Properties.Contains("new_category") == true)

    nextNumber = ((

    Picklist)results.Properties["new_category"]).Value + 1;

    }

     

    return nextNumber;

    }

    }

    }

    20 июля 2009 г. 8:15
  • Добрый день.

    Итак вопросы:

    1. Что есть такое поле new_sowing.
    2. В каком поле хранится ссылка на родительский объект (lookup).
    3. Имя схемы родительской сущности.
    4. Какое поле в родительской сущности необходимо обновить (picklist) со значениями $, $$, $$$.
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    20 июля 2009 г. 9:41
  • Добрый день.

    Итак вопросы:

    1. Что есть такое поле new_sowing.
    2. В каком поле хранится ссылка на родительский объект (lookup).
    3. Имя схемы родительской сущности.
    4. Какое поле в родительской сущности необходимо обновить (picklist) со значениями $, $$, $$$.
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    Отвечаю:
    1. new_sowing - это дочерняя сущность
    2. в поле new_clientid
    3. new_client
    4. new_category
    20 июля 2009 г. 9:58
  • Добрый день.

    Ещё вопрос - при изменении какого поля в дочерней сущности должно выполняться изменение категории в родительской, и какой его тип - int или decimal и дайте пожалуйста табличку сопоставлений. Например:

    до 100 - $
    от 100 до 200 - $$
    свыше 200 - $$$

    и табличку сопоставления значений пиклиста. Я так понимаю, что $ - 1, $$ - 2, $$$ - 3.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    20 июля 2009 г. 10:28
  • Добрый день.

    Ещё вопрос - при изменении какого поля в дочерней сущности должно выполняться изменение категории в родительской, и какой его тип - int или decimal и дайте пожалуйста табличку сопоставлений. Например:

    до 100 - $
    от 100 до 200 - $$
    свыше 200 - $$$

    и табличку сопоставления значений пиклиста. Я так понимаю, что $ - 1, $$ - 2, $$$ - 3.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    При изменении поля (int) new_squre.
    Сопоставления такие:
    1. до 10000 - $
    2. от 10000 до 50000 - $$
    3. от 50000 до 100000 - $$$

    ПикЛист Вы правильно написали
    20 июля 2009 г. 10:31
  • Добрый день.

    Попробуйте следующий код:

    using System;
    using System.Collections.Generic;
    using Microsoft.Win32;
    using Microsoft.Crm.Sdk;
    using Microsoft.Crm.SdkTypeProxy;
    using Microsoft.Crm.SdkTypeProxy.Metadata;
    using Microsoft.Crm.Sdk.Query;
    using System.Web.Services.Protocols;
    
    namespace Crm.Plugins
    {
        public class ClientAutoCategory : IPlugin
        {
            public void Execute(IPluginExecutionContext context)
            {
                try
                {
                    if (context.InputParameters.Properties.Contains(ParameterName.Target) &&
                    context.InputParameters.Properties[ParameterName.Target] is DynamicEntity)
                    {
                        DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];
                        if (entity.Name == "new_sowing" && entity.Properties.Contains("new_squre"))
                        {
                            int square = ((CrmNumber)entity.Properties["new_squre"]).Value;
                            int targetvalue = 0;
    
                            if (square <= 10000)
                                targetvalue = 1;
                            else if (square <= 50000)
                                targetvalue = 2;
                            else
                                targetvalue = 3;
    
                            Guid parententityid = ((Lookup)((DynamicEntity)context.PreEntityImages["PreUpdate"])["new_clientid"]).Value;
    
                            ICrmService service = context.CreateCrmService(true);
    
                            DynamicEntity parententity = new DynamicEntity("new_client");
                            parententity["new_clientid"] = new Key(parententityid);
                            parententity["new_category"] = new Picklist(targetvalue);
                            service.Update(parententity);
                        }
                    }
                }
                catch (SoapException exc)
                {
                    throw new Exception(exc.Detail.InnerText);
                }
            }
        }
    
    }
    
    При регистрации плагина Вам потребуется зарегистрировать Image c именем PreUpdate - это потребуется для получения идентификатора родительского объекта, потому как при обновлении только в случае изменения этого поля - значение будет в контексте плагина.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    • Предложено в качестве ответа Andrii ButenkoMVP 20 июля 2009 г. 11:10
    20 июля 2009 г. 10:42
  • Добрый день.

    Попробуйте следующий код:

    using System;
    
    using System.Collections.Generic;
    
    using Microsoft.Win32;
    
    using Microsoft.Crm.Sdk;
    
    using Microsoft.Crm.SdkTypeProxy;
    
    using Microsoft.Crm.SdkTypeProxy.Metadata;
    
    using Microsoft.Crm.Sdk.Query;
    
    using System.Web.Services.Protocols;
    
    
    
    namespace Crm.Plugins
    
    {
    
        public class ClientAutoCategory : IPlugin
    
        {
    
            public void Execute(IPluginExecutionContext context)
    
            {
    
                try
    
                {
    
                    if (context.InputParameters.Properties.Contains(ParameterName.Target) &&
    
                    context.InputParameters.Properties[ParameterName.Target] is DynamicEntity)
    
                    {
    
                        DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];
    
                        if (entity.Name == "new_sowing" && entity.Properties.Contains("new_squre"))
    
                        {
    
                            int square = ((CrmNumber)entity.Properties["new_squre"]).Value;
    
                            int targetvalue = 0;
    
    
    
                            if (square <= 10000)
    
                                targetvalue = 1;
    
                            else if (square <= 50000)
    
                                targetvalue = 2;
    
                            else
    
                                targetvalue = 3;
    
    
    
                            Guid parententityid = ((Lookup)((DynamicEntity)context.PreEntityImages["PreUpdate"])["new_clientid"]).Value;
    
    
    
                            ICrmService service = context.CreateCrmService(true);
    
    
    
                            DynamicEntity parententity = new DynamicEntity("new_client");
    
                            parententity["new_clientid"] = new Key(parententityid);
    
                            parententity["new_category"] = new Picklist(targetvalue);
    
                            service.Update(parententity);
    
                        }
    
                    }
    
                }
    
                catch (SoapException exc)
    
                {
    
                    throw new Exception(exc.Detail.InnerText);
    
                }
    
            }
    
        }
    
    
    
    }
    
    
    
    
    При регистрации плагина Вам потребуется зарегистрировать Image c именем PreUpdate - это потребуется для получения идентификатора родительского объекта, потому как при обновлении только в случае изменения этого поля - значение будет в контексте плагина.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    Спасибо огромное, работает. Последний вопросик. Допустим в дочернем несколько записей с площадями. Они все по разным годам. Например,
    2008 - 10000
    2009 - 20000
    Мне необходимо изменять в главной сущности категорию только по последнему году сверять.
    • Помечено в качестве ответа Sergii BielskyiMVP 20 июля 2009 г. 11:27
    20 июля 2009 г. 10:53
  • Добрый день.

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

    if (((CrmNumber)((DynamicEntity)context.PreEntityImages["PreUpdate"])[<поле года>]).Value != DateTime.Now.Year)
        return;

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    • Предложено в качестве ответа Andrii ButenkoMVP 20 июля 2009 г. 11:10
    20 июля 2009 г. 11:10
  • Добрый день.

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

    if (((CrmNumber)((DynamicEntity)context.PreEntityImages["PreUpdate"])[<поле года>]).Value != DateTime.Now.Year)
        return;

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    Не знаю даже как Вас благодарить. Спасибо огромное. Всё работает :). Кстати, если не секрет, откуда Вы такое знаете? Может подскажете литературу.
    20 июля 2009 г. 11:21
  • Добрый день.

    Благодарность выражается нажатием под ответом кнопки пометить как ответ и нажатиями на Проголосовать за сообщение как полезное ) Этого вполне достаточно. По поводу откуда я знаю - скачал SDK и почитал. И всем рекомендую. Описание короткое, но достаточное для осмысления.
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    • Помечено в качестве ответа Sergii BielskyiMVP 20 июля 2009 г. 11:27
    20 июля 2009 г. 11:26
  • Добрый день.

    Благодарность выражается нажатием под ответом кнопки пометить как ответ и нажатиями на Проголосовать за сообщение как полезное ) Этого вполне достаточно. По поводу откуда я знаю - скачал SDK и почитал. И всем рекомендую. Описание короткое, но достаточное для осмысления.
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

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

    Guid

     

    parententityid = new Guid();

     

    if (context.MessageName == "Update")

    parententityid = ((

    Lookup)((DynamicEntity)context.PreEntityImages["PreUpdate"])["new_clientid"]).Value;

     

    if (context.MessageName == "Create")

    parententityid = ((

    Lookup)((DynamicEntity)context.PostEntityImages["PostUpdate"])["new_clientid"]).Value;

    Ну а дальше всё как было написано сверху.

    Мне выдаётся ошибка - Ключ не был найде в словаре. Что может быть?

    21 июля 2009 г. 5:16
  • Добрый день.

    Благодарность выражается нажатием под ответом кнопки пометить как ответ и нажатиями на Проголосовать за сообщение как полезное ) Этого вполне достаточно. По поводу откуда я знаю - скачал SDK и почитал. И всем рекомендую. Описание короткое, но достаточное для осмысления.
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

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

    Guid

     

    parententityid = new Guid();

     

     

    if (context.MessageName == "Update")

    parententityid = ((

     

    Lookup)((DynamicEntity)context.PreEntityImages["PreUpdate"])["new_clientid"]).Value;

     

     

    if (context.MessageName == "Create")

    parententityid = ((

     

    Lookup)((DynamicEntity)context.PostEntityImages["PostUpdate"])["new_clientid"]).Value;

    Ну а дальше всё как было написано сверху.

    Мне выдаётся ошибка - Ключ не был найде в словаре. Что может быть?

    Эта ошибка возникает при создании записи в дочернем. (Данный ключ не был найден в словаре)
    21 июля 2009 г. 6:35
  • Добрый день.

    В случае создания идентификатор родительской записи можно получить непосредственно из контекста. Можете воспользоваться таким кодом:

    Guid parententityid = ((Lookup)entity["new_clientid"]).Value;


    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    21 июля 2009 г. 9:10
  • Добрый день.

    В случае создания идентификатор родительской записи можно получить непосредственно из контекста. Можете воспользоваться таким кодом:

    Guid parententityid = ((Lookup)entity["new_clientid"]).Value;


    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    Вот написал:

    Guid

     

    parententityid = new Guid();

     

    if (context.MessageName == "Update")

    parententityid = ((

    Lookup)((DynamicEntity)context.PreEntityImages["PreUpdate"])["new_clientid"]).Value;

     

    else

    parententityid = ((

    Lookup)entity["new_clientid"]).Value;

     

    ICrmService service = context.CreateCrmService(true);

     

    DynamicEntity parententity = new DynamicEntity("new_client");

    parententity[

    "new_clientid"] = new Key(parententityid);

    parententity[

    "new_category"] = new Picklist(targetvalue);

    service.Update(parententity);

     

     

     


    Но Всё равно таже ошибка при создании записи

    21 июля 2009 г. 9:17
  • Добрый день.

    В случае создания убедитесь, что поле new_clientid заполнено.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    21 июля 2009 г. 9:28
  • Добрый день.

    В случае создания убедитесь, что поле new_clientid заполнено.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    100 % заполнено.
    21 июля 2009 г. 9:29
  • Добрый день.

    В случае создания убедитесь, что поле new_clientid заполнено.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    я запись дочернего создаю непосредственно с главного
    21 июля 2009 г. 9:29
  • Добрый день.

    Тогда рекомендую заняться отладкой при помощи Visual Studio. Благо про отладку плагинов немало написано.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    21 июля 2009 г. 9:31
  • Добрый день.

    Тогда рекомендую заняться отладкой при помощи Visual Studio. Благо про отладку плагинов немало написано.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    :) кстати при отладке, когда пытаюсь подключиться к процессу удалённому, получается ошибка:
    Unable to attach to the process. The Visual Studio Remote Debugger has insufficient privileges to debug this process...
    21 июля 2009 г. 9:37
  • Добрый день.

    Тогда рекомендую заняться отладкой при помощи Visual Studio. Благо про отладку плагинов немало написано.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    :) кстати при отладке, когда пытаюсь подключиться к процессу удалённому, получается ошибка:
    Unable to attach to the process. The Visual Studio Remote Debugger has insufficient privileges to debug this process...
    Сам решил, надо просто под админ правами запускать.
    21 июля 2009 г. 9:39
  • Добрый день.

    Тогда рекомендую заняться отладкой при помощи Visual Studio. Благо про отладку плагинов немало написано.

    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com

    Спасибо, отладка меня спасла. Нашёл проблему. Просто вверху была ссылка на образ, которого нет
    21 июля 2009 г. 10:03