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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.08.2009, 12:41   #1  
Roman08 is offline
Roman08
Участник
 
93 / 29 (1) +++
Регистрация: 27.02.2008
Адрес: Украина; Житомир
Записей в блоге: 1
Создание экземпляра кастомной сущности из плагина
Здравствуйте! Прошу совета - как мне программно в плагине создать экземпляр кастомной сущности? Аналогично task entity = new task(). Писать свой конструктор? или для этого используется другой механизм ? Я нашел, как здесь на форуме обсуждалось подобное создание через SOAP запрос. Если создание на c# описано в SDK - буду очень благодарен за линк. Спасибо.
Старый 27.08.2009, 12:50   #2  
Bondonello is offline
Bondonello
Kostya Afendikov
Аватар для Bondonello
MCBMSS
Лучший по профессии 2009
 
510 / 106 (5) +++++
Регистрация: 06.06.2008
Адрес: Украина
Читайте про DynamicEntity (в SDK все есть)
Как пример:
http://ms-dynamics-crm.com.ua/2009/0...ugin-ms-crm-4/
За это сообщение автора поблагодарили: Roman08 (1).
Старый 27.08.2009, 12:51   #3  
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
Поисковик.

Результаты:
http://nishantrana.wordpress.com/200...t-dynamic-crm/
http://ms-dynamics-crm.com.ua/2009/0...ugin-ms-crm-4/
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством.

Подписывайтесь на мой блог, twitter и YouTube канал.
Пользуйтесь моим Ultimate Workflow Toolkit
За это сообщение автора поблагодарили: Roman08 (1).
Старый 28.08.2009, 14:17   #4  
Roman08 is offline
Roman08
Участник
 
93 / 29 (1) +++
Регистрация: 27.02.2008
Адрес: Украина; Житомир
Записей в блоге: 1
Cпасибо за линки, разбираюсь... Вот что пишется в лог файле: The entity with a name = 'none' was not found in the MetadataCache., ErrorCode: -2147217150
Насколько я понимаю, конструкция
DynamicEntity entityM = new DynamicEntity();

entityM.Name = "<имя кастомной сущности>";

не работает. Поэтому такой вопрос - правильно ли я присваиваю имя, или нужен запрос в Metadata? или что-то другое - чтобы идентифицировать эту сущность?
Спасибо.
Старый 28.08.2009, 14:57   #5  
Bondonello is offline
Bondonello
Kostya Afendikov
Аватар для Bondonello
MCBMSS
Лучший по профессии 2009
 
510 / 106 (5) +++++
Регистрация: 06.06.2008
Адрес: Украина
можете выложить весь код?
опишите задачу, которую пытаетесь реализовать: как регистрируете плагин и прочее...
Старый 28.08.2009, 21:15   #6  
Roman08 is offline
Roman08
Участник
 
93 / 29 (1) +++
Регистрация: 27.02.2008
Адрес: Украина; Житомир
Записей в блоге: 1
Задача - создать связанный с opportunity объект сущности tcc_oppmonthly при измененении opportunity. Поле связи - tcc_monthlydetailsid.
//values for fields - заготовка, мне надо разделить значение поля estimatedvalue на некое значение и записать результат в поле tcc_value вновь создаваемой сущности.
Код:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;

namespace MonthlyOppDetail
{
    public class MonthDetailCreationHandler : IPlugin
    {
        #region IPlugin Members
        public void Execute(IPluginExecutionContext context)
        {
            if (context.MessageName == MessageName.Update
                && context.InputParameters.Contains("Target") 
                && context.InputParameters["Target"] is DynamicEntity)
            {
                DynamicEntity entity = (DynamicEntity)context.InputParameters["Target"];
                //Check that target entity is opportunity
                if (entity.Name != EntityName.opportunity.ToString())
                    return;

                //Check that this opportunity has entered needed fields
                if (!entity.Properties.Contains("estimatedvalue"))
                    return;

                //values for fields
                decimal sum         = ((CrmMoney)entity.Properties["estimatedvalue"]).Value;
                CrmMoney sum223     = new CrmMoney();
                sum223.Value        = sum / 2;

                ICrmService crmservice = context.CreateCrmService(true);

                DynamicEntity       entityM         = new DynamicEntity();
                TargetCreateDynamic targetCreate    = new TargetCreateDynamic();
                CreateRequest       createRequest   = new CreateRequest();

                entityM.Name = "tcc_oppmonthly";
               
                CrmMoneyProperty _Tcc_value = new CrmMoneyProperty();
                _Tcc_value.Name                 = "tcc_value";
                _Tcc_value.Value                = sum223; 
                entityM.Properties.Add(_Tcc_value);
                
                KeyProperty _tcc_monthlydetailsid = new KeyProperty();
                _tcc_monthlydetailsid.Name  = "tcc_monthlydetailsid";
                _tcc_monthlydetailsid.Value = (Key)entity.Properties["opportunityid"];
                entityM.Properties.Add(_tcc_monthlydetailsid);
                
                targetCreate.Entity = entityM;
                createRequest.Target = targetCreate;

                crmservice.Create(entityM);

            }
        }
        #endregion IPlugin Members
    }
}
Регистрацию провожу на Post событие Update, Parent pipeline . В синхронном режиме - в файл трассировки записано только "The entity with a name = 'none' was not found in the MetadataCache., ErrorCode: -2147217150". В асинхронном - также |Level: Error | MessageProcessor.Execute
>MessageProcessor fail to process message 'Create' for 'tcc_oppmonthly'.
[2009-08-28 19:35:56.0] Process: w3wp |Organization:959e4b7c-ab67-dd11-b616-000c29704829 |Thread: 6 |Category: Platform.Sdk |User: b04a20e9-ab67-dd11-b616-000c29704829 |Level: Error | DefaultExceptionHandler.Handle
>CrmSoapExtension detected non-CrmException - report will be sent to Watson:
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.InvalidCastException: Unable to cast object of type 'Microsoft.Crm.Sdk.KeyProperty' to type 'Microsoft.Crm.Sdk.LookupProperty'.


Пока не могу понять - почему KeyProperty ошибка есть только в одном режиме.
Заранее благодарен за указание ошибок.
Спасибо.
Старый 28.08.2009, 21:50   #7  
Bondonello is offline
Bondonello
Kostya Afendikov
Аватар для Bondonello
MCBMSS
Лучший по профессии 2009
 
510 / 106 (5) +++++
Регистрация: 06.06.2008
Адрес: Украина
Жаль, что поздно ответили, на выходных не смогу посмотреть, а уровень пока не дотягивает, чтобы в уме откомпилить и найти ошибку
Попробуйте дебажить ваш плагин по шагам, я думаю так вы гораздо быстрее найдете правильное решение
Пример для отладки плагина http://ms-dynamics-crm.com.ua/2009/0...namics-crm-40/

UPD: Еще обратите внимание на это
Цитата:
Unable to cast object of type 'Microsoft.Crm.Sdk.KeyProperty' to type 'Microsoft.Crm.Sdk.LookupProperty'.
Это относится к этой части
X++:
 KeyProperty _tcc_monthlydetailsid = new KeyProperty();
, здесь должен быть Lookup а не Key

Последний раз редактировалось Bondonello; 28.08.2009 в 23:27.
За это сообщение автора поблагодарили: Roman08 (1).
Старый 29.08.2009, 01:18   #8  
Roman08 is offline
Roman08
Участник
 
93 / 29 (1) +++
Регистрация: 27.02.2008
Адрес: Украина; Житомир
Записей в блоге: 1
2 Bondonello -
Спасибо большое за участие, поблагодарить единицей смогу чуть позже ;-), сам я ушел в отладку :-)
Старый 30.08.2009, 16:21   #9  
maclai is offline
maclai
Участник
 
14 / 11 (1) +
Регистрация: 09.10.2008
Попробуйте GUID instead key:
примерно так:
Guid pricelevelGuid = new Guid(((Key)entity1.Properties["pricelevelid"]).Value.ToString());
Старый 30.08.2009, 18:25   #10  
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
Цитата:
Сообщение от maclai Посмотреть сообщение
Попробуйте GUID instead key:
примерно так:
Guid pricelevelGuid = new Guid(((Key)entity1.Properties["pricelevelid"]).Value.ToString());
Зачем так сложно. Упрощать надо. Примерно так:

Guid pricelevelGuid = ((Key)entity1.Properties["pricelevelid"]).Value;
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством.

Подписывайтесь на мой блог, twitter и YouTube канал.
Пользуйтесь моим Ultimate Workflow Toolkit
Старый 31.08.2009, 16:55   #11  
Roman08 is offline
Roman08
Участник
 
93 / 29 (1) +++
Регистрация: 27.02.2008
Адрес: Украина; Житомир
Записей в блоге: 1
Объединив идеи предыдущих постов , получил следующий код для заполнения поля связи с родительской сущностью:
Цитата:
Guid oppid = ((Key)preOpp.Properties["opportunityid"]).Value;
LookupProperty _tcc_monthlydetailsid = new LookupProperty();
_tcc_monthlydetailsid.Name = "tcc_monthlydetailsid";
_tcc_monthlydetailsid.Value = new Lookup(EntityName.opportunity.ToString(), oppid);
entityM.Properties.Add(_tcc_monthlydetailsid);
Теперь не могу пока разрешить следующую коллизию - создание значения ГУИДа для DynamicEntity. Для системных используется конструкция
X++:
accountID = service.Create(myAccount);
Если я совсем не прописываю свойства для поля ГУИД в коде , то получаю ошибку - что параметр со значением NULL не передается; если же хочу инициализировать просто через new Key()- то в логах пишет "Attribute: tcc_oppmonthlyid cannot be set to NULL", что справедливо, т.к. значение генерится одними нулями с разделителем.
В результате - следующая конструкция с захардкореным ГУИДом работает, но ведь мне нужно генерить его динамически...
X++:
KeyProperty _tcc_oppmonthlyid = new KeyProperty();
  _tcc_oppmonthlyid.Name          = "tcc_oppmonthlyid";
  _tcc_oppmonthlyid.Value = new Key(new Guid("A0FAD8FE-6468-DA11-B748-000D9DD8CDAC"));
  entityM.Properties.Add(_tcc_oppmonthlyid);
Подскажите, пожалуйста, как мне правильно "разрулить" эту ситуацию? Как задать создание ГУИДа перед вызовом Execute? Спасибо.

Последний раз редактировалось Roman08; 31.08.2009 в 17:02.
Старый 31.08.2009, 17:02   #12  
Bondonello is offline
Bondonello
Kostya Afendikov
Аватар для Bondonello
MCBMSS
Лучший по профессии 2009
 
510 / 106 (5) +++++
Регистрация: 06.06.2008
Адрес: Украина
Собственно говоря не только для системных используется такая конструкция
accountID = service.Create(myAccount);
Т.е. перед тем как обновить созданную вами запись ее сначала необходимо создать, гуид так и получайте Guid guidID = service.Create(myCustomEntity);

Последний раз редактировалось Bondonello; 31.08.2009 в 17:04.
Старый 31.08.2009, 17:15   #13  
Bondonello is offline
Bondonello
Kostya Afendikov
Аватар для Bondonello
MCBMSS
Лучший по профессии 2009
 
510 / 106 (5) +++++
Регистрация: 06.06.2008
Адрес: Украина
Приведу небольшой пример, чтобы легче было въехать (мне так и самому всегда проще)

X++:
// Спецификация к договору
            DynamicEntity do_salescontractspec = new DynamicEntity("do_salescontractspec");
            do_salescontractspec.Properties.Add(new OwnerProperty("ownerid", new Owner("systemuser", ((Owner)_quote["ownerid"]).Value)));

            Lookup quoteLookup = new Lookup();
            quoteLookup.Value = quoteid;
            quoteLookup.type = EntityName.quote.ToString();

            //связываю с ком. предложением
            do_salescontractspec.Properties.Add(new LookupProperty("do_quote", quoteLookup));
            //указываею имя, как и у ком. пред.
            do_salescontractspec.Properties.Add(new StringProperty("do_name", _quote["name"].ToString()));

            //customer
            do_salescontractspec.Properties.Add(new LookupProperty("do_account", new Lookup("account", ((Customer)_quote["customerid"]).Value)));
            //do_account - client customerid

            //firma
            do_salescontractspec.Properties.Add(new LookupProperty("do_firm", new Lookup("do_firms", ((Lookup)_quote["do_firm"]).Value)));

            //vid torgovli
            do_salescontractspec.Properties.Add(new PicklistProperty("do_sale_type", new Picklist(((Picklist)_quote["do_paymenttype"]).Value)));
            //tip ucheta 
            do_salescontractspec.Properties.Add(new PicklistProperty("do_accountingtype", new Picklist(((Picklist)_quote["do_accountingtype"]).Value)));
            
           //Создаю спецификаю и сразу же получаю ее Guid, чтобы потом привязывать к ней продукты
            Guid specGuid = crmService.Create(do_salescontractspec);

            Lookup specLookup = new Lookup();
            specLookup.Value = specGuid;
            specLookup.type = "do_salescontractspec";
Обратите внимание на

X++:
           //Создаю спецификаю и сразу же получаю ее Guid, чтобы потом привязывать к ней продукты
            Guid specGuid = crmService.Create(do_salescontractspec);

            Lookup specLookup = new Lookup();
            specLookup.Value = specGuid;
            specLookup.type = "do_salescontractspec";
Я создаю новую запись и сразу получаю ее гуид, ну а затем уже привязываю и делаю все что мне надо
За это сообщение автора поблагодарили: Roman08 (1).
Старый 31.08.2009, 19:10   #14  
Roman08 is offline
Roman08
Участник
 
93 / 29 (1) +++
Регистрация: 27.02.2008
Адрес: Украина; Житомир
Записей в блоге: 1
2 Bondonello -
Благодарность "1" смогу выразить позже :-) Получается юзер гайд для новичков.
Если использую конструкцию
X++:
Guid _OppDetailId = crmservice.Create(entityM);
, то тогда не нужен код для метода Execute:
X++:
CreateResponse created = (CreateResponse)crmservice.Execute(createRequest);
, который описывает Ваша статья ? Потому что в этом случае у меня создалось две идентичные записи ;-). Т.е. я создаю экземпляр DynamicEntity без TargetCreateDynamic и CreateRequest - просто через Create - я правильно Вас понял?
Старый 31.08.2009, 21:34   #15  
Bondonello is offline
Bondonello
Kostya Afendikov
Аватар для Bondonello
MCBMSS
Лучший по профессии 2009
 
510 / 106 (5) +++++
Регистрация: 06.06.2008
Адрес: Украина
Есть несколько вариантов, сам еще постоянно учусь
Да, таким макаром
X++:
Guid _OppDetailId = crmservice.Create(entityM);
вы создадите запись + получите ее гуид в переменную _OppDetailId
Просто сразу настраивайте проект для отладки, мне так намного проще было начинать, да и сейчас тоже удобно
Теги
plugin, экземпляр

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как получить значение поля одной сущности при обработке формы другой сущности zhenek Dynamics CRM: Разработка 25 05.07.2011 16:19
Как создать экземпляр кастомной сущности через SOAP? Tony Green Dynamics CRM: Разработка 7 27.02.2009 08:37
Создание и регистрация плагина на Execute и Retreive a33ik Dynamics CRM: Разработка 7 30.11.2008 15:03
Модификая контекста плагина ZooY Dynamics CRM: Разработка 3 28.09.2008 13:52
Создание объекта сущности из другого объекта! SnSS Dynamics CRM: Разработка 5 29.05.2008 13:38

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

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

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