0

Want to learn how to develop a Dynamics CRM C# Plugin? Try Dynamics Edge’s Dynamics CRM Plugin Developer Training course to help you extend your D365 / D365CE / Dynamics CRM  system beyond your wildest dreams for greater success that fits your specific organization’s unique needs and goals.

Dynamics CRM C# Plugin Developer Training Dynamics Edge

When it comes to Dynamics 365 developer training, selecting the one that best fits your specific organization’s needs may be most useful to you. With Dynamics Edge’s Dynamics 365 training options, you can even request a custom course to fit your organization’s specific situation, including courses that are at a more advanced level than those courses you may find for free online with a Google Search, or even when paid, alternative courses that are only specifically tailored to exams or boilerplate material you may have already seen before.

Contact Dynamics Edge for more info on going beyond the boilerplate and seeing if our courses may fit your unique needs. We offer many options, including those which may be tailored for your specific scenarios.

How do I become a CRM Dynamics developer?

To become a Dynamics CRM Developer, it is important to know that most employers prefer applicants with skills and experience in the specific area in which they work. In some cases, extensive, relevant, and high quality hands-on experience could even outweigh both college degrees and industry-specific certifications, depending on the depth, level of experience, context, and other factors related to the specific kind of experience you may bring to the table.

One potential simple answer is that you can gain practical hands-on experience through our hands-on Dynamics 365 training courses at Dynamics Edge, as part of your quest to answering the question of “How do I become a CRM Dynamics developer?” or “How do I become a Dynamics CRM developer?”

You can develop your Dynamics 365 / Dynamics CRM plugin development skills by taking courses offered by Dynamics Edge, and relevant certifications offered by Microsoft that some Dynamics Edge courses may even help you potentially prepare for. You can also try working on personal projects, such as those that may be inspired by taking Dynamics Edge’s Dynamics 365 CRM training courses, to gain experience with Dynamics CRM development, or even by contributing to open-source projects. Demonstrating relevant experience in C# programming and Dynamics CRM can significantly boost your marketability and confidence when seeking new job opportunities in this field.

What is the plugin code for creating a new record?

In order to write the Dynamics CRM C# Plugin code that ends up creating a new record, the specific steps may depend on the context and requirements of the plugin. However, in general, you would first create a new project in Visual Studio and add references to the necessary libraries. Then, you would write code to extend the appropriate interface, such as IPlugin, and implement the necessary methods, such as Execute. Within the Execute method, you would write code to create a new record of the desired entity type, such as Lead, Account, or Opportunity, and set its attributes. You may also need to handle any necessary validations or error handling. Once the code is written and tested, you can build the project and register the plugin with Dynamics CRM using the Plugin Registration Tool.

To further go into “What is the plugin code for creating a new record?” you may want to consider the following. As an example, consider creating a new Lead with a plugin. For that, you would first define the necessary attributes for the Lead entity, such as the lead’s name and contact information. Then, within the Execute method of your plugin, you would create a new instance of the Lead entity, set its attributes to the desired values, and save it to the database using the appropriate service methods.

Similarly, to create a new Account with a plugin, you would define the necessary attributes for the Account entity and create a new instance of the entity within the Execute method.

To create a new Opportunity with a plugin, you would follow similar steps, defining the necessary attributes and creating a new instance of the Opportunity entity within the Execute method. Additionally, you would typically associate an Account with the Opportunity by setting the “customerid” attribute of the Opportunity entity to the ID of the related Account. For example:

Entity opportunity = new Entity("opportunity");
opportunity["name"] = "New Opportunity";
opportunity["customerid"] = new EntityReference("account", accountId);

This example demonstrates how to associate an existing Account with the newly created Opportunity by setting the “customerid” attribute to an EntityReference object that references the related Account.

EntityReference is a class in the Dynamics CRM SDK that represents a reference to an entity in the system. It is used to establish relationships between different entities, particularly when working with lookup fields. Lookup fields in Dynamics CRM allow users to establish relationships between records in different entities, which can be useful for organizing and relating data in a meaningful way.

There are two types of lookup fields in CRM: single-valued lookups and multi-valued lookups (also known as party lists). Single-valued lookups represent a single relationship between two entities, while multi-valued lookups can represent multiple relationships between entities. Lookup fields are closely related to the concept of relationships in CRM, as they allow entities to be linked together in various ways.

There are three main types of relationships in CRM: one-to-many (1:N), many-to-one (N:1), and many-to-many (N:N). These relationships are used to define how different entities are connected to each other and how they can be interacted with.

Here are three simple examples to demonstrate the different types of relationships, using the Opportunity entity:

Many-to-one (N:1) relationship:

For example, many Opportunities can be associated with one Account, meaning that one Account record can be associated with one or more Opportunities. From the point of view of the Opportunity, this is usually represented by a lookup field on the Opportunity form. While one Opportunity is associated with one Account via Lookup field, it does not imply a 1:1 relationship; it simply means that you are viewing the N:1 relationship from the perspective of the Opportunity entity, from the point of view of one Opportunity record.

In this case, (which may be the simpler, more straightforward case) when creating a new Opportunity with a C# plugin and then associating it with an existing Account, you can associate the new Opportunity with an existing Account using an EntityReference:

Entity opportunity = new Entity("opportunity");
opportunity["name"] = "New Opportunity";
opportunity["customerid"] = new EntityReference("account", accountId);

In this example, we first create a new Account record and then update the existing Opportunity’s “customerid” lookup field to reference the new Account, establishing the N:1 relationship between the Opportunity and the Account.

One-to-many (1:N) relationship:

An example that may make sense here, is that one Account can have many Opportunities. When you are viewing an Account record, you can usually see the associated Opportunities in a subgrid on the Account form.

Does that seem familiar? Yes – this is actually using the exact same relationship! The only difference is we’re looking at it from the 1 side now (the Account side).

As mentioned, when looking at the relationship from a single Opportunity Record’s point of view, if you see a lookup field on a record’s form (e.g. the Account Lookup field on the form of an Opportunity record), it indicates that the current entity (e.g. Opportunity) is on the N side of an N:1 relationship, and the entity represented in the lookup field (e.g. Account) is on the 1 side.

So essentially, when you see a Lookup field on a form, you are likely looking at a relationship from the perspective of a single record (e.g. Opportunity Record), where that record’s Table (Opportunity) is on the many (N) side of the relationship, and the table represented by the record in the Lookup field (e.g. Account) is on the 1 side of the Relationship.

However, here’s another way to look at the same relationship. When looking at the relationship from a single Account Record’s point of view If you see a Subgrid on a record’s form (e.g. a Subgrid of Opportunities on an Account record’s form), it indicates that the current entity (Account) is on the 1 side of a 1:N relationship, and the entity represented in the subgrid (e.g. Opportunity) is on the N side.

So essentially, when you see a Subgrid on a form, you are likely looking at a relationship from the perspective of a single record (e.g. Account Record), where that record’s Table (Account) is on the one (1) side of the relationship, and the table represented by the records present in the subgrid (of which there can be 0, 1 or more than 1) (e.g. Opportunity) is on the many (N) side of the Relationship.

Now, let’s consider an example where you want to create a new Account (1 side) and associate it with an existing Opportunity (N side). Since we are creating a new Account and want to associate it with an existing Opportunity, we need to update the existing Opportunity’s “customerid” lookup field to reference the newly created Account.


// Create the new Account
Entity account = new Entity("account");
account["name"] = "New Account";
Guid accountId = service.Create(account);

// Retrieve the existing Opportunity
Guid opportunityId = my_existing_opportunity_id;
ColumnSet columns = new ColumnSet("opportunityid", "customerid");
Entity opportunity = service.Retrieve("opportunity", opportunityId, columns);

// Update the Opportunity's customerid lookup field to reference the new Account
opportunity["customerid"] = new EntityReference("account", accountId);
service.Update(opportunity);

In this example, we first create a new Account record (1 side) and then update the existing Opportunity’s (N side) “customerid” lookup field to reference the new Account, establishing the N:1 relationship between the Opportunity and the Account.

As you may have noticed, EntityReference (the C# class) is primarily used to represent the 1 side entity in the context of the relationship. The EntityReference constructor is called with the entity type and ID of the record on the 1 side of a 1:N relationship, such as

new EntityReference("account", accountId).

In a 1:N relationship, while EntityReference (the C# class) is not usually directly used on the 1 side, it plays a crucial role in establishing the connection between the 1 side and N side entities. The relationship is established implicitly when you create or update the related N side records with the lookup field set to the 1 side entity’s ID using an EntityReference. By doing this, the N side record’s lookup field points to the 1 side entity, and the 1 side entity can have multiple N side records associated with it through this relationship.

Many-to-many (N:N) relationship:

Suppose there is a many-to-many relationship between Event and Attendee entities. To associate an existing Event with an existing Attendee, you would first

1. Get the Event, here’s a possible example how you might do this:

// Assuming 'service' is an instance of IOrganizationService
string entityLogicalName = "new_event"; // Replace with the actual logical name of the Event entity
string eventName = "My Event";

// Create a QueryExpression with the specified entity logical name
QueryExpression query = new QueryExpression(entityLogicalName);

// Define the columns (attributes) to retrieve
query.ColumnSet = new ColumnSet("new_event_name");

// Add a condition to filter events by the given name
query.Criteria.AddCondition("new_event_name", ConditionOperator.Equal, eventName);

// Execute the query and retrieve the results
EntityCollection results = service.RetrieveMultiple(query);

// Check if there's at least one record that matches the criteria
if (results.Entities.Count > 0)
{
// Retrieve the first matching Event entity
Entity eventEntity = results.Entities[0];

// Get the Event's GUID
Guid eventId = eventEntity.Id;

//if needed, repeat this again for attendeeId

string attendeeLogicalName = "new_attendee";
string attendeeName = "My Attendee";

QueryExpression attendeeQuery = new QueryExpression(attendeeLogicalName);

attendeeQuery.ColumnSet = new ColumnSet("new_attendee_name");

attendeeQuery.Criteria.AddCondition("new_attendee_name", ConditionOperator.Equal, attendeeName);

EntityCollection attendeeResults = service.RetrieveMultiple(attendeeQuery);

if (attendeeResults.Entities.Count > 0)
{

Entity attendeeEntity = attendeeResults.Entities[0];

Guid attendeeId = attendeeEntity.Id;

// Do something with the Event and Attendee entity record (e.g., update or associate with each other)
}
else
{
// Handle the case when no matching Attendee is found
}
}
else
{
// Handle the case when no matching Event is found
}

2. Now, inside the
// Do something with the Event and Attendee entity record (e.g., update or associate with each other)
part, retrieve the relationship schema name and then use the Associate method. Here’s an example using RetrieveRelationshipRequest to retrieve the relationship by name:

// Assuming 'eventId' and 'attendeeId' variables are defined.
string relationshipSchemaName = "new_event_attendee"; // Replace with the correct schema name
// Retrieve the relationship using the schema name

RetrieveRelationshipRequest request = new RetrieveRelationshipRequest
{
Name = relationshipSchemaName
};
RetrieveRelationshipResponse response = (RetrieveRelationshipResponse)service.Execute(request);
RelationshipMetadataBase relationshipMetadata = response.RelationshipMetadata;

// Alternatively, you can use the following line to create a Relationship object directly
// Relationship relationship = new Relationship(relationshipSchemaName);

// Now, Create a Relationship object using the retrieved metadata
Relationship relationship = new Relationship(relationshipMetadata.SchemaName);
EntityReferenceCollection relatedEntities = new EntityReferenceCollection();
relatedEntities.Add(new EntityReference("attendee", attendeeId));

// Associate the Event with the Attendee
service.Associate("event", eventId, relationship, relatedEntities);

For #2 above, a simpler, more direct alternative that might work, could be to use this instead:


Relationship relationship = new Relationship(relationshipSchemaName);

EntityReferenceCollection relatedEntities = new EntityReferenceCollection();

relatedEntities.Add(new EntityReference("attendee", attendeeId));

// Associate the Event with the Attendee
service.Associate("event", eventId, relationship, relatedEntities);

As you can see, it may be possible to use new Relationship(relationshipSchemaName) directly, which could be a simpler approach. However, using RetrieveRelationshipRequest might allow you to access additional metadata about the relationship if needed.

To make an Event that is already currently associated with an Attendee, to be no longer associated with the Attendee, simply use Dissociate instead of Associate:

// Disassociate the Event from the Attendee
service.Disassociate("event", eventId, relationship, relatedEntities);

In this example, the N:N relationship is managed through an intermediate table that connects Events and Attendees. The Associate method takes care of creating the necessary records in the intermediate table.

For 1:N relationships, you can follow a similar approach. Here’s an example of how to associate an existing Opportunity with an existing Account using the Associate method:

// Assuming 'accountId' and 'opportunityId' variables are defined
string relationshipSchemaName = "account_opportunities"; // Replace with the correct schema name

// Retrieve the relationship using the schema name
RetrieveRelationshipRequest oneToManyRequest = new RetrieveRelationshipRequest
{
Name = relationshipSchemaName
};
RetrieveRelationshipResponse oneToManyResponse = (RetrieveRelationshipResponse)service.Execute(oneToManyRequest);
OneToManyRelationshipMetadata oneToManyRelationshipMetadata = (OneToManyRelationshipMetadata)oneToManyResponse.RelationshipMetadata;

// Create a Relationship object using the retrieved metadata
Relationship oneToManyRelationship = new Relationship(oneToManyRelationshipMetadata.SchemaName);
EntityReferenceCollection relatedEntities = new EntityReferenceCollection();
relatedEntities.Add(new EntityReference("opportunity", opportunityId));

// Associate the Account with the Opportunity
service.Associate("account", accountId, oneToManyRelationship, relatedEntities);

Next, we can disassociate the Opportunity from the Account using the Disassociate method:

// Disassociate the Account from the Opportunity
service.Disassociate("account", accountId, oneToManyRelationship, relatedEntities);

In Power Fx in Power Apps Canvas App, you can achieve similar functionality using Relate and Unrelate functions. Here’s an example:

First, associate an existing Opportunity with an existing Account using the Relate function:

// Assuming 'accountRecord' and 'opportunityRecord' are records of Account and Opportunity tables respectively
Relate(accountRecord.'Opportunities (account_opportunities)', opportunityRecord)

Next, disassociate the Opportunity from the Account using the Unrelate function:

Unrelate(accountRecord.'Opportunities (account_opportunities)', opportunityRecord)

In both the Dynamics CRM C# examples and the Power Fx examples, the code snippets demonstrate how Associate and Disassociate (or Relate and Unrelate) can be used for 1:N relationships, allowing you to establish or remove relationships between records effectively.

For the sake of additional example, if we were using Power Fx in a Power Apps Canvas App, and we were using the Event and Attendee N:N example, we would use the Relate and Unrelate functions like this:

First, associate an existing Attendee with an existing Event using the Relate function:

// Assuming 'eventRecord' and 'attendeeRecord' are records of Event and Attendee tables respectively
Relate(eventRecord.'Attendees (event_attendees)', attendeeRecord)

Next, disassociate the Attendee from the Event using the Unrelate function:

Unrelate(eventRecord.'Attendees (event_attendees)', attendeeRecord)

In this Power Fx example, the code snippets demonstrate how Relate and Unrelate can be used for N:N relationships in a Power Apps Canvas App, allowing you to establish or remove relationships between records effectively, similar to the C# code snippets provided earlier.

Note that any example code snippets provided in this article are intended for reference only. You should try it in a Sandbox environment. Example code snippets on this page, if any are present, are not guaranteed to work or to be free of errors, as they are intended for initial reference purposes only. If you want more in-depth help, we suggest you to contact us for more information.

By understanding the different types of relationships and how EntityReference, as well as Associate and Disassociate, are used to establish them, you can effectively work with lookup fields and related entities in Dynamics CRM.

If you have experience with C# and Dynamics CRM but have concerns about whether your experience is sufficient for creating production C# plugins for organizations, focusing on enhancing your knowledge through training, certifications, or practical experience can help you build the confidence and expertise needed to excel in this field.

Contact Dynamics Edge for more info on how we can help you build your confidence in Dynamics, gain more practical experience or prepare for certifications with our Dynamics CRM Training so you could dive deeper into Dynamics and achieve greater excellence and success today, tomorrow, and every day.

Finally, let’s close with one more question:

Is looking at Subgrids and Lookup Fields really the way to identify 1:N and N:1?

For review – consider 1:N and N:1 relationships – when a Lookup field is present, it suggests that the current entity is on the N side, and when a Subgrid is present, it suggests that the current entity is on the 1 side. And that the relationship is the same one, we’re just looking at it from either the 1 side or the N side. So the Account Lookup Field on an Opportunity Form means we know this about a particular relationship that is working behind the scenes for that specific field:

  • Account to Opportunity is 1:N – which means one Account can have zero, one, or more than one associated Opportunities
  • Opportunity to Account is N:1, which means the same thing as the above
    • More specifically, one Opportunity record can be associated with either no Account, or one specific Account by the Lookup field,
    • However, another Opportunity record may be associated with either no account, that very same Account as the other Opportunity was also associated with, or an entirely different Account
    • By knowing this, we can even predict that if we look at the Account side, we can either see, (or know that there is a potential to create and make available) a Subgrid on the Account form, for which all the rows (if any exist) shown (imagining that it’s set to show all records, and ignoring any caveats like Security Role restrictions, etc. for now) must be the very same Opportunities that also have that specific Account Record set as the value for the Opportunity Record’s Account Lookup field.
  • This is actually the same relationship, just looked at from two different angles.

In general, using Lookup fields and Subgrids as indicators of relationships in this way is reliable. However, you should be aware of some edge cases or potential pitfalls:

Customizations: It’s possible that a system administrator has customized the form and removed or modified the Lookup field or Subgrid. This may cause an incomplete or inaccurate view of the relationship. It’s essential to review the actual entity relationships in the system rather than relying solely on the form presentation.

Inactive relationships: If a relationship has been deactivated, the Lookup field or Subgrid may still be present on the form, but the relationship might not be active or functional. In such cases, the form presentation might be misleading.

Complex relationships: If the relationship involves more than two entities or is a part of a larger web of relationships, relying solely on Lookup fields and Subgrids for understanding the relationship might not provide a complete picture.

Security roles: User permissions can impact the visibility of Lookup fields and Subgrids. If a user doesn’t have the necessary permissions to view related records, the Lookup field or Subgrid may not be visible, leading to an incomplete understanding of the relationship.

While these cases are relatively uncommon, it’s essential to consider them when using Lookup fields and Subgrids to understand relationships. In general, though, using Lookup fields and Subgrids as described here can provide quick and useful information about the relationships between entities.

You should also know that just because there is no subgrid or no lookup field on the form, does not mean that the relationship is not present. For example, suppose there was no Account lookup field on the Opportunity form. This should not be used to suggest that a 1:N relationship between Account and Opportunity does not exist! In other words, to know all the relationships present on a Table (formerly known as an Entity), you don’t want to rely solely on the forms and presentation. In this scenario, the common saying “Absence of evidence is not evidence of absence” might apply quite well here and you are advised to heed it in this case!

To learn even more, contact Dynamics Edge to see how we can help you learn how to start leveraging Dynamics CRM today to achieve greater success outcomes for you and your organization tomorrow.

Have a Question ?

Fill out this short form, one of our Experts will contact you soon.

Call Us Today For Your Free Consultation