27.08.2009, 12:41 | #1 |
Участник
|
Создание экземпляра кастомной сущности из плагина
Здравствуйте! Прошу совета - как мне программно в плагине создать экземпляр кастомной сущности? Аналогично task entity = new task(). Писать свой конструктор? или для этого используется другой механизм ? Я нашел, как здесь на форуме обсуждалось подобное создание через SOAP запрос. Если создание на c# описано в SDK - буду очень благодарен за линк. Спасибо.
|
|
27.08.2009, 12:50 | #2 |
Kostya Afendikov
|
Читайте про DynamicEntity (в SDK все есть)
Как пример: http://ms-dynamics-crm.com.ua/2009/0...ugin-ms-crm-4/ |
|
|
За это сообщение автора поблагодарили: Roman08 (1). |
27.08.2009, 12:51 | #3 |
Чайный пьяница
|
Поисковик.
Результаты: 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 |
Участник
|
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 |
Kostya Afendikov
|
можете выложить весь код?
опишите задачу, которую пытаетесь реализовать: как регистрируете плагин и прочее... |
|
28.08.2009, 21:15 | #6 |
Участник
|
Задача - создать связанный с 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 } } >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 |
Kostya Afendikov
|
Жаль, что поздно ответили, на выходных не смогу посмотреть, а уровень пока не дотягивает, чтобы в уме откомпилить и найти ошибку
Попробуйте дебажить ваш плагин по шагам, я думаю так вы гораздо быстрее найдете правильное решение Пример для отладки плагина 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(); Последний раз редактировалось Bondonello; 28.08.2009 в 23:27. |
|
|
За это сообщение автора поблагодарили: Roman08 (1). |
29.08.2009, 01:18 | #8 |
Участник
|
2 Bondonello -
Спасибо большое за участие, поблагодарить единицей смогу чуть позже ;-), сам я ушел в отладку :-) |
|
30.08.2009, 16:21 | #9 |
Участник
|
Попробуйте GUID instead key:
примерно так: Guid pricelevelGuid = new Guid(((Key)entity1.Properties["pricelevelid"]).Value.ToString()); |
|
30.08.2009, 18:25 | #10 |
Чайный пьяница
|
Цитата:
Guid pricelevelGuid = ((Key)entity1.Properties["pricelevelid"]).Value;
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством. Подписывайтесь на мой блог, twitter и YouTube канал. Пользуйтесь моим Ultimate Workflow Toolkit |
|
31.08.2009, 16:55 | #11 |
Участник
|
Объединив идеи предыдущих постов , получил следующий код для заполнения поля связи с родительской сущностью:
Цитата:
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); X++: accountID = service.Create(myAccount); В результате - следующая конструкция с захардкореным ГУИДом работает, но ведь мне нужно генерить его динамически... 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); Последний раз редактировалось Roman08; 31.08.2009 в 17:02. |
|
31.08.2009, 17:02 | #12 |
Kostya Afendikov
|
Собственно говоря не только для системных используется такая конструкция
accountID = service.Create(myAccount); Т.е. перед тем как обновить созданную вами запись ее сначала необходимо создать, гуид так и получайте Guid guidID = service.Create(myCustomEntity); Последний раз редактировалось Bondonello; 31.08.2009 в 17:04. |
|
31.08.2009, 17:15 | #13 |
Kostya Afendikov
|
Приведу небольшой пример, чтобы легче было въехать (мне так и самому всегда проще)
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 |
Участник
|
2 Bondonello -
Благодарность "1" смогу выразить позже :-) Получается юзер гайд для новичков. Если использую конструкцию X++: Guid _OppDetailId = crmservice.Create(entityM); X++: CreateResponse created = (CreateResponse)crmservice.Execute(createRequest); |
|
31.08.2009, 21:34 | #15 |
Kostya Afendikov
|
Есть несколько вариантов, сам еще постоянно учусь
Да, таким макаром X++: Guid _OppDetailId = crmservice.Create(entityM); Просто сразу настраивайте проект для отладки, мне так намного проще было начинать, да и сейчас тоже удобно |
|
Теги |
plugin, экземпляр |
|
|