Answered by:
CRM 2013 - C# Plugin

Question
-
Hi
I was wondering if it was possible to access another entity and their fields while the plugin is working on another.
I am working on a Entity called 'Orders'
In orders the user can create an address, I want to be able to get the data that's in a field called 'Address Code' which is in the Entity 'Address'
The Entity address is a out of the box entity which I understand has many limitations
Will it be possible to do what I want?
Thanks, Shaun
S.Harrison
Wednesday, June 18, 2014 10:57 AM
Answers
-
Hi Shaun,
The following code would do the job:
ConditionExpression condition1 = new ConditionExpression(); condition1.AttributeName = "parentid"; condition1.Operator = ConditionOperator.Equal; condition1.Values.Add("A99D25C4-AFD5-E311-946F-D89D6765B134"); //have your account/contact id here FilterExpression filter1 = new FilterExpression(); filter1.Conditions.Add(condition1); filter1.FilterOperator = LogicalOperator.And; QueryExpression query = new QueryExpression("customeraddress"); query.ColumnSet.AddColumns("addressnumber"); query.Criteria.AddFilter(filter1);
EntityCollection result1 = _serviceProxy.RetrieveMultiple(query);
Admin QuikView Solution for CRM 2013
- Edited by Anupam Bishui Wednesday, June 18, 2014 12:37 PM
- Marked as answer by Shaun Harrison Monday, June 30, 2014 11:41 AM
Wednesday, June 18, 2014 12:37 PM -
I have resolved the issue
My code was as follows
IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
I needed to declare service not context in the line
EntityCollection result1 = context.RetrieveMultiple(query);
It needed to be
EntityCollection result1 = service.RetrieveMultiple(query);
Thanks for all your help
Shaun
S.Harrison
- Marked as answer by Shaun Harrison Monday, June 30, 2014 11:41 AM
Thursday, June 19, 2014 8:36 AM -
Another change for anyone who is wanting to do something similar was
condition1.Values.Add(accountCode);
This gave errors as the query was looking for an id and accountCode was providing a EntityReference
the line was changed to
condition1.Values.Add(accountID.Id);
Everything now works as I wanted
Thanks to everyone for their help
S.Harrison
- Marked as answer by Shaun Harrison Monday, June 30, 2014 11:41 AM
Thursday, June 19, 2014 8:48 AM
All replies
-
Hi Shaun,
Of course that is possible. You can create a query any entity irrespective of the entity against which the Plugin is executing. All you need is to create a query in Plugin which can be done by different methods like QueryExpression or FetchXML or LinQ and fire that query using RetrieveMultiple method and retrieve data.
Have a look at these links :
http://msdn.microsoft.com/en-us/library/gg334607.aspx
http://msdn.microsoft.com/en-us/library/gg328149.aspx
Admin QuikView Solution for CRM 2013
- Proposed as answer by HIMBAPModerator Wednesday, June 18, 2014 11:42 AM
- Edited by Anupam Bishui Wednesday, June 18, 2014 11:53 AM typo
Wednesday, June 18, 2014 11:03 AM -
As said you can write your query based on your condition and define which attribute you want to fetch, refer this to see diffent options if you want to use queryexpression
You can see here methods supported by address entity
Our Website| Our Blog | Follow US | My Facebook Page | Microsoft Dynamics CRM 2011 Application Design
Make sure to "Vote as Helpful" and "Mark As Answer",if you get answer of your question.- Proposed as answer by HIMBAPModerator Wednesday, June 18, 2014 11:42 AM
Wednesday, June 18, 2014 11:42 AMModerator -
Thanks both
So from reading the links provided I feel that QueryExpression would be the best option
Address Entity can have multiple retrieve method which is what I need
From the example code given I have customized the following to suit what I want
(I realized that I need address number not Address Code)
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "addressnumber";
//Can the two lines below be removed as I'm not looking for a certain address number
condition1.Operator = ConditionOperator.Equal;
condition1.Values.Add("Brown");//
FilterExpression filter1 = new FilterExpression();
filter1.Conditions.Add(condition1);
QueryExpression query = new QueryExpression("address");
query.ColumnSet.AddColumns("addressnumber");
query.Criteria.AddFilter(filter1);
EntityCollection result1 = _serviceProxy.RetrieveMultiple(query);From here the example code used a loop to print out each result in a console application
however im using a class library therefore I don't need to print out all the information
I do however need to be able to use it
Would putting the data into a array be best?
Thanks, Shaun
S.Harrison
- Edited by Shaun Harrison Wednesday, June 18, 2014 12:04 PM
Wednesday, June 18, 2014 12:02 PM -
ConditionExpression condition1 = new ConditionExpression();
condition1.AttributeName = "ConditionalAttributename"; // you need to provide field which you want to compare to get address codecondition1.Operator = ConditionOperator.Equal;
condition1.Values.Add("Conditionalattributevalue"); //corresponding value
FilterExpression filter1 = new FilterExpression();
filter1.Conditions.Add(condition1);
QueryExpression query = new QueryExpression("address");
query.ColumnSet.AddColumns("addressnumber");
query.Criteria.AddFilter(filter1);Our Website| Our Blog | Follow US | My Facebook Page | Microsoft Dynamics CRM 2011 Application Design
Make sure to "Vote as Helpful" and "Mark As Answer",if you get answer of your question.Wednesday, June 18, 2014 12:08 PMModerator -
Hi
I realized that I need account number not account code, therefore in the code I posted I had
condition1.AttributeName = "addressnumber";
Also as I'm not looking for a certain value, I want to get all of the addresses do I need the two lines that follow which are
condition1.Operator = ConditionOperator.Equal;
condition1.Values.Add("Brown");The reason I don't want a certain value is because I'm going to be creating a new address, for each address they have to have a unique account code
From the account number I can retrieve the highest number in the Addresses and simply add 1 to it.
Thanks, Shaun
S.Harrison
Wednesday, June 18, 2014 12:15 PM -
Hi Shaun,
If your objective is to retrieve all CustomerAddress records in Dynamics CRM, you may as well omit the Filter part. So your query would look like:
QueryExpression query = new QueryExpression("customeraddress"); query.ColumnSet.AddColumns("addressnumber"); EntityCollection result1 = _serviceProxy.RetrieveMultiple(query);
Once you get the data, if I were you, I would add them to a List. You can add them to an array as well, but I prefer to use a List<string> as adding is easier.
But remember, you'll get multiple records having the same "addressnumber" as they are unique only for a specific account/record. This means say Account1 can have 1,2,3 as address numbers; but this won't prevent another account say Account2 to have 1,2 and 3 as well.
Admin QuikView Solution for CRM 2013
- Edited by Anupam Bishui Wednesday, June 18, 2014 12:19 PM
Wednesday, June 18, 2014 12:16 PM -
Hi
That makes more sense, Thank you
As you mentioned on the last bit of your post, is it possible to only retrieve Addresses that are linked to the account I'm working on?
I have access to the account code which is unique to each account therefore is there a way to filter using that?
Thanks, Shaun
S.Harrison
Wednesday, June 18, 2014 12:26 PM -
Hi Shaun,
The following code would do the job:
ConditionExpression condition1 = new ConditionExpression(); condition1.AttributeName = "parentid"; condition1.Operator = ConditionOperator.Equal; condition1.Values.Add("A99D25C4-AFD5-E311-946F-D89D6765B134"); //have your account/contact id here FilterExpression filter1 = new FilterExpression(); filter1.Conditions.Add(condition1); filter1.FilterOperator = LogicalOperator.And; QueryExpression query = new QueryExpression("customeraddress"); query.ColumnSet.AddColumns("addressnumber"); query.Criteria.AddFilter(filter1);
EntityCollection result1 = _serviceProxy.RetrieveMultiple(query);
Admin QuikView Solution for CRM 2013
- Edited by Anupam Bishui Wednesday, June 18, 2014 12:37 PM
- Marked as answer by Shaun Harrison Monday, June 30, 2014 11:41 AM
Wednesday, June 18, 2014 12:37 PM -
Hi
Thanks!
So to add to a list I would have the query the length of the returns so that I could create a loop to insert all results into the list?
Thanks, Shaun
S.Harrison
Wednesday, June 18, 2014 12:47 PM -
Hi
I've just noticed that you have inputted a certain account/contact id in the query
I need it to be able to work for every account/contact not just one
Thanks, Shaun
S.Harrison
Wednesday, June 18, 2014 1:01 PM -
Hi Shaun,
You're right. You can iterate as follows:
if (result1 !=null && result1.Entities.Count > 0) { List<string> _addresses = new List<string>(); foreach (Entity _entity in result1.Entities) { _addresses.Add(_entity.Attributes["addressnumber"].ToString()); } }
Wednesday, June 18, 2014 1:03 PM -
Hi Shaun,
You can provide any contact/account Id and the code will fetch all addresses related to that contact/account. Now if you want to iterate through all contacts/accounts addresses; you'll need to first fetch all contact/account Ids and then fetch their addresses. Or if you want to fetch all addresses that existed for any contact/account, remove the filter criteria.
Admin QuikView Solution for CRM 2013
- Edited by Anupam Bishui Wednesday, June 18, 2014 1:05 PM
Wednesday, June 18, 2014 1:04 PM -
Hi
I'll try explaining again, I want any account/contact that is being worked on be able to retrieve their relate addresses
I have already have access to a account code via the following
varaccountCode = ((Microsoft.Xrm.Sdk.EntityReference)(accountCodePostImage.Attributes["accountid"]));
varaccountID = service.Retrieve(accountCode.LogicalName, accountCode.Id, newColumnSet(true));
varactualID = accountID["new_accountcode"].ToString();
Could I use instead of the following;
condition1.Values.Add("A99D25C4-AFD5-E311-946F-D89D6765B134");
Use;
condition1.Values.Add(accountCode);
Thanks, Shaun
S.Harrison
Wednesday, June 18, 2014 1:17 PM -
Hi,
Yes, you could directly query it using the account id you're retrieving using
var accountCode = ((Microsoft.Xrm.Sdk.EntityReference)(accountCodePostImage.Attributes["accountid"])); condition1.Values.Add(accountCode);
Admin QuikView Solution for CRM 2013
- Edited by Anupam Bishui Wednesday, June 18, 2014 1:31 PM
Wednesday, June 18, 2014 1:27 PM -
Hi,
No, new_accountcode is only used in Accounts Entity, I have done the changes and all seems well so far
However, the issue I have is that Visual Studio is saying that
_serviceProxy does not exist in the current context
And I'm struggling to find a solution
Thanks, Shaun
S.Harrison
Wednesday, June 18, 2014 1:33 PM -
Hi Shaun,
Are you using the following line to create the service proxy?
IPluginExecutionContext _serviceProxy = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
Wednesday, June 18, 2014 1:43 PM -
Hi,
Ah right, yes I'm using that line however instead of _serviceProxy I have context.
I have done the change, however now I have a error stating that
Microsoft.Xrm.Sdk.IPluginExecutionContext does not contain a definition for 'RetrieveMultiple' and no extention method 'RetrieveMultiple' accepting a first argument of type 'Microsoft.Xrm.Sdk.IPluginExecutionContext could not be found
Thanks Shaun
S.Harrison
Wednesday, June 18, 2014 1:55 PM -
Make sure you add the Microsoft.Xrm.Sdk.dll as reference to your project and have the following usings:
using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query;
Wednesday, June 18, 2014 2:03 PM -
Hi
Those are both also there
Thanks, Shaun
S.Harrison
Wednesday, June 18, 2014 2:10 PM -
Hi,
Just to be clear the error is still there
Thanks, Shaun
S.Harrison
Wednesday, June 18, 2014 2:58 PM -
Hi,
Try adding the "using Microsoft.Xrm.Sdk.Client;". Also did you double click on the RetrieveMultiple method? It generally adds the necessary using. Also make sure you've actually added the Microsoft.Xrm.Sdk.dll to your project reference by Right Click on Project > Add Reference > Browse for Microsoft.Xrm.Sdk.dll from the CRM SDK > OK
Wednesday, June 18, 2014 4:41 PM -
Hi
Client is already there, tried double clicking and nothing, and the .dll is already there
Still error message showing
Thanks, Shaun
S.Harrison
Thursday, June 19, 2014 7:46 AM -
I have resolved the issue
My code was as follows
IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
I needed to declare service not context in the line
EntityCollection result1 = context.RetrieveMultiple(query);
It needed to be
EntityCollection result1 = service.RetrieveMultiple(query);
Thanks for all your help
Shaun
S.Harrison
- Marked as answer by Shaun Harrison Monday, June 30, 2014 11:41 AM
Thursday, June 19, 2014 8:36 AM -
Another change for anyone who is wanting to do something similar was
condition1.Values.Add(accountCode);
This gave errors as the query was looking for an id and accountCode was providing a EntityReference
the line was changed to
condition1.Values.Add(accountID.Id);
Everything now works as I wanted
Thanks to everyone for their help
S.Harrison
- Marked as answer by Shaun Harrison Monday, June 30, 2014 11:41 AM
Thursday, June 19, 2014 8:48 AM