23.08.2011, 16:03 | #1 |
Участник
|
CRM 2011 Получение пользователя по его роли безопасности
Пробую так
запрос: QueryExpression query = new QueryExpression("role") { Criteria = { Conditions = { new ConditionExpression() { AttributeName = "name", Operator = ConditionOperator.Equal, Values = {"Ведущий бухгалтер"} } } } }; Получаю роль var rolesResponse = service.RetrieveMultiple(query); Все верно 1 роль var role = rolesResponse.Entities.FirstOrDefault(); Далее нужно по этой роли выбрать пользователя. Тут не могу сообразить как верно сформировать запрос. Пробовал так: query = new QueryExpression("systemuser") { Criteria = { Conditions = { new ConditionExpression() { AttributeName = "systemuserroles_association", Operator = ConditionOperator.Equal, Values = {role.Id} } } } }; в итоге получаю ответ что поля systemuserroles_association не существует, но ведь связка называется именно так. Как правильно сформировать запрос, чтобы выбрать связанную сущность с той что у меня уже есть (не только касаемо данной задачи, а вообще). Спасибо |
|
23.08.2011, 16:52 | #2 |
Чайный пьяница
|
Добрый день.
1. Незачем это делать через 2 обращения к вебсервису - 1-го вполне достаточно. 2. Сущность связи - systemuserroles, а не systemuserroles_association.
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством. Подписывайтесь на мой блог, twitter и YouTube канал. Пользуйтесь моим Ultimate Workflow Toolkit |
|
23.08.2011, 20:17 | #3 |
Moderator
|
Согласен с Андреем: одним запросом в данном случае выбрать проще. Если вам сложно разобраться с тем как это делается при помощи QueryExpresion, в SDK есть примеры как сделать то же при помощи LINQ. В любом случае в справке написано как связывать записи и строить ограничения по полям связанных сущностей.
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. MS Certified Dirty Magic Professional |
|
24.08.2011, 07:35 | #4 |
Участник
|
Может я копаю где-то не в той степи. Какую справку Вы имеете ввиду?
Я догадываюсь что в данном случае я использую лишний вопрос, но правильный вариант пока не вижу. LINQ знаю, но как его использовать в данном случае пока не могу понять. ___________________ UPD: Насколько я понимаю для того чтобы сделать это одним запросом необходимо подключить вторую сущность. Для этого как я понимаю предназначен query.AddLink(), но тем не менее до меня до сих пор остается загадкой через какой атрибут связана сущность systemuser с сущностью role. query = new QueryExpression("systemuser"); query.AddLink("role", "?","?",JoinOperator.Inner) Я так понимаю дело именно в том что сущности связаны как N:N, но как с этим работать я пока понять не могу. Последний раз редактировалось KP0H; 24.08.2011 в 09:19. |
|
24.08.2011, 10:03 | #5 |
Чайный пьяница
|
SDK
Цитата:
Сообщение от KP0H
UPD: Насколько я понимаю для того чтобы сделать это одним запросом необходимо подключить вторую сущность.
Для этого как я понимаю предназначен query.AddLink(), но тем не менее до меня до сих пор остается загадкой через какой атрибут связана сущность systemuser с сущностью role. query = new QueryExpression("systemuser"); query.AddLink("role", "?","?",JoinOperator.Inner) Я так понимаю дело именно в том что сущности связаны как N:N, но как с этим работать я пока понять не могу. Код, который можно использовать для построения запроса по выборке пользователей для определённой роли: Код: QueryExpression q = new QueryExpression("systemuser"); q.ColumnSet = new ColumnSet(new string[] { "systemuserid" }); LinkEntity link = q.AddLink("systemuserroles", "systemuserid", "systemuserid"); link = link.AddLink("role", "roleid", "roleid"); link.LinkCriteria.AddCondition("name", ConditionOperator.Equal, "Ведущий бухгалтер");
__________________
Эмо разработчик, сначала пишу код, потом плачу над его несовершенством. Подписывайтесь на мой блог, twitter и YouTube канал. Пользуйтесь моим Ultimate Workflow Toolkit |
|
|
За это сообщение автора поблагодарили: KP0H (1). |
24.08.2011, 10:41 | #6 |
Участник
|
Спасибо. Уже практически разобрался с LinkEntity, но немного перемудрил.
|
|
24.08.2011, 10:49 | #7 |
Moderator
|
Под справкой понимается SDK по системе. Там есть масса примеров построения запросов как через "классическую" объектную модель, так и при помощи XRMContext с использованием модели LINQ. Я думаю вам просто нужно потратить некоторое время на самообразование.
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. MS Certified Dirty Magic Professional |
|
24.08.2011, 11:37 | #8 |
Участник
|
Бесспорно надо, просто дело в том что в целом проблем при работе не возникает за исключением каких-то мелких как в итоге оказывается ньюансов, которые сильно стопорят.
Дело в том что в данном случае я пишу plugin, и как я понимаю сущности которые можно сгенерировать с помощью crmsvcutil.exe для прокси здесь не уместны, а чтобы работать с LINQ нужно создавать отдельный контекст, в то время как в плагин уже приходит исполнимый контекст. |
|
24.08.2011, 13:17 | #9 |
Участник
|
В продолжении темы. Выбрать нужных пользователей получилось. Среди них по опредиленному алгоритму выбран один, который должен быть назначен в качестве ответственного.
В результате получаю ошибку: Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Download the details and load with Plug-in Profiler. ....................................................................................................|Detail: <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts"> <ErrorCode>-2147220891</ErrorCode> <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic"> <KeyValuePairOfstringanyType> <d2p1:key>OperationStatus</d2p1:key> <d2p1:value xmlns:d4p1="http://www.w3.org/2001/XMLSchema" i:type="d4p1:int">0</d2p1:value> </KeyValuePairOfstringanyType> </ErrorDetails> <Message>Download the details and load with Plug-in Profiler. .......................................................................................................</Message> <Timestamp>2011-08-24T09:09:50.5222849Z</Timestamp> <InnerFault i:nil="true" /> <TraceText> [PluginProfiler.Plugins: PluginProfiler.Plugins.ProfilerPlugin] [01e336b0-30ce-e011-82f4-00155d02de0e: BusinessAccountingPlugins.AccountRegistrationPlugin: Create of account (Profiler)] Ну и далее соответственно мой текст трэйса. Судя по которому плагин выполнился полностью. Сначала я подумал что у роли "Ведущий бухгалтер" не хватает привелегий, и действительно так и оказалось. При установке руками появлялось сообщение что у пользователя надостаточно привилегий. После установки: чтение, назначение, запись, общий доступ в ручную назначить получается. А через плагин не получается. Я пробовал менять: newAccount.Attributes["owninguser"] = user.Attributes["systemuserid"]; и newAccount.Attributes["ownerid"] = user.Attributes["systemuserid"]; Эффект тот же. Насколько я понимаю ErrorCode -2147220891 говорит о "ISV code aborted the operation.". Но в чем причина? Плагин работает в контексте моего пользователя, следовательно с теми же правами что и я работая через веб-интефейс. // Obtain the execution context from the service provider. Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext) serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext)); IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); UPD: Как я понимаю owninguser только для чтения, значит логично что нужно менять ownerid, но service.Update(newAccount) не выполняет изменений. Последний раз редактировалось KP0H; 24.08.2011 в 14:08. |
|
24.08.2011, 14:18 | #10 |
Участник
|
Собственно причина видимо в том что нужно присваивать EntityReference, а не Guid.
Разбираюсь. Пробую так: newAccount.Attributes["ownerid"] = new EntityReference("systemuser", (Guid)user.Attributes["systemuserid"]); - по сути это должен быть верный вариант. но что-то не фартит мне сегодня) newAccount.Attributes["ownerid"] = new EntityReference(user.LogicalName, user.Id); Не могу понять что тут не верно. Или напрямую это вообще не будет работать и нужно разбираться с AssignRequest? Последний раз редактировалось KP0H; 24.08.2011 в 15:37. |
|
24.08.2011, 15:20 | #11 |
Участник
|
Или напрямую это вообще не будет работать и нужно разбираться с AssignRequest?
|
|
24.08.2011, 16:04 | #12 |
Участник
|
AssignRequest assign = new AssignRequest()
{ Assignee = new EntityReference(user.LogicalName, user.Id), Target = new EntityReference(newAccount.LogicalName, newAccount.Id) }; //service.Update(newAccount); AssignResponse response = (AssignResponse)service.Execute(assign); Вот так все отработало и Ответственный за организацию сменился. Но в системных заданиях все равно отметка о состоянии - не выполнено. И сообщение о неотловленном исключении... Это баг или фича? |
|
24.08.2011, 19:11 | #13 |
Moderator
|
Некоторые поля, например, Owner, State, Status, не обновляются в сообщении Update. Их изменение - отдельное бизнес событие в CRM и оно должно вызываться отдельным сообщением Assign, SetState и т.д.
Вообще ваш монолог наталкивает на мысль, что вы способны сомообучаться, что хорошо. Пожалуйста, не пишите на форум, как только возникает проблема. Путь профессионала - это самообразование. Задавайте вопрос, если проблему не удается решить собственными силами. Для всего остального есть Твитер.
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. MS Certified Dirty Magic Professional |
|
|
За это сообщение автора поблагодарили: KP0H (1). |
24.08.2011, 19:16 | #14 |
Moderator
|
Цитата:
Очевидно ваш плагин отрабатывает снаружи системной транзакции, так что его операции не откатываются после падения. Какая-то из строчек кода, которая идет после успешно выполненных операций выбрасывает исключение, поэтому в системных заданиях операция числится проваленой. Просто отладте свой код и все будет хорошо.
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. MS Certified Dirty Magic Professional |
|
24.08.2011, 20:11 | #15 |
Участник
|
Дело в том что в данный момент последняя строчка кода идет AssignResponse response = (AssignResponse)service.Execute(assign);
После этого закрывается блок try и начинается catch, который собственно не отлавливает никакой ошибки. Поэтому я немного не понимаю на данный момент всю соль ситуации, но с работой самого плагина в принципе разобрался, завтра займусь "Работой над ошибками". Еще один вопрос. Plug-in Profiler по своей сути это вообще что за зверь? Ну собственно пока это продолжение монолога. В любом случае разбираться уже буду завтра. Зато быть может кому-то мой монолог сэкономит 8 часов работы) В Google по моим запросам эта тема выпадает первой))) |
|
24.08.2011, 21:43 | #16 |
Moderator
|
Возможно плагин не обновился и в базе все еще старая сборка. Де-ба-гинг...
__________________
http://fixrm.wordpress.com, снятие/наведение порчи. Быстро, дорого, гарантия. MS Certified Dirty Magic Professional |
|
25.08.2011, 07:33 | #17 |
Участник
|
Последний интересующий меня вопрос по существу:
Download the details and load with Plug-in Profiler - это означает что есть какая-то утилита, которой можно скачать лог и посмотреть? Если есть то как она называется и где её искать? |
|
Теги |
query, пользователи, роли, запрос (query) |
|
|