Dynamics Workflow Scope

I ran into a scenario this week, where  workflow I created was only running for my user account on records that I had created and not ones that I might later modify and/or that other people had created.

The solution was to change the scope of the workflow to Organization so it ran for everyone.

Changing from User (the default) to Organization got this going.  I haven’t had a need to try with the current user’s business unit which would be pretty cool too.

org

Alternate Keys in Dynamics

In CRM 2015 Update 1, a new concept for allowing a field to be listed as a primary key outside of the traditional Guids was introduced called Alternate Keys.  I had not had a chance to use this feature in-depth so thought this would be a great opportunity to dig into it.

The concept itself is pretty simple – you are integrating Dynamics with another system that has it’s own setup of Primary Keys why not replicate those Ids in Dynamics.  If you are deploying a greenfield solution with no integrations to other systems, you’ll probably never use this feature.  However, if you have a complex synchronization solution between many line of business solutions where an entity in Dynamics could actually represent 5 disparate resources throughout the rest of your organization, this could be a big win for you.

Creating an Alternate key is pretty easy and can be done from the entity section in Dynamics.

key1.PNG

From here you then identify your field as an alternate key in the new “keys” section of your entity.

key2

Which will then show as an alternate key in the Keys section.

Key3

Without any other configuration, your new “key” field automatically has Duplicate data detection on it, ensuring that each record has a unique value as a key within it.  If a duplicate value is identified, the following warning is presented to the user.

key4

As someone who writes migration/syncing code quite a bit, this is a great way to manage a variety of keys from different environments and ensure data is not getting dirtied.  There are some additional SDK functions that enable you to create entities from the alternate key as well.

My only confusion with this feature was that when you mark the field as “an Alternate Key” it doesn’t make it Business Required by default.  As a unique key, allowing empty values (even one should not be allowed).

Dynamics365 is not a Database

Yes, it has a database that stores all of it’s information within it, but it is not a database.

Similar to Skype For Business and SharePoint that have databases to store all of it’s configuration models and user data within it, they are not referred to as databases.

Over the years I’ve been asked many times to take a customer’s existing database model and map it to Dynamics – i., pick up and replace.

This generally leads to a back and forth on how this should be done as we discuss legacy information, schemas that no longer apply or are used and features that can simplify the overall implementation of the schema.

I think part of the reason for this is the readability of the Dynamics schema whereas something like SharePoint and Skype For Business is much more obscured (or a bit harder to read) whereas Dynamics can be readily mapped to the SDK.

When “migrating” a schema it’s important to remember;

  1. Your current schema for state engines will be replaced with State/Status codes for Dynamics.
  2. Your user ownership will be replaced by createdBy/modifiedBy entries tied to an active directory (on premise or in the cloud) and not use application Ids.
  3. Many-2-Many tables will exist in Dynamics but will not necessarily be accessible to you.
  4. Auditing is a checkbox that you enable.

I think what would really benefit Dynamics in this regard, and where I feel the Solution Designer falls down, is not providing a proper Entity Relationship Model for both the logical and physical implementation.  When talking with end users, it’s the logical they are more concerned with – “are all of our concepts within there” – and the developers who are more concerned with the physical – “can I get all my datatypes and fields in there”.

In the end, I urge customers not to think of their Dynamics implementation as database with an application on top of it, but instead of a platform that are creating, extending and debugging.

No code I know, but had to get this out there – it’s not a Database!

Creating Your Own Business Unit

Business Units are one of those dicey concepts in Dynamics where if done right – they make sense and are of big value to your implementation.

But when done wrong, they can be a black hole that makes your life very hard to recover from.

When discussing with clients why they need a business unit there are a few things I generally look for;

  • Do you have groups within your organization that need to keep their data separate from one another?  The best example being a parent company with subsidiaries which need to use the same system but cannot see each other’s data (because they are partners).
  • Are you trying to do implement security with a Business Unit (i.e., what people can and cannot do?).  If so, you should look at security roles.

Generally, when implementing Business Units, I encourage customers not to go too many levels deep in their first implementation.

On a recent project, I had to some solution deployment code and wanted to figure out how to create a Business Unit from the SDK.  The key to the creation of any business unit is the hierarchy so the first thing you need to do is get the reference to the parent business unit id where you want your business unit to reside in.

Once you have done that, it’s as easy as creating the business unit code, assigning the new EntityReference and creating the object.

QueryExpression query = new QueryExpression("businessunit")
{
ColumnSet = new ColumnSet(true)
};

EntityCollection businessunits = cn.CrmService.RetrieveMultiple(query);
if (businessunits.Entities.Count == 1)
{
Entity busunit = new Entity("businessunit");
busunit["name"] = "Test Greg Unit";
busunit["parentbusinessunitid"] = new EntityReference("businessunit", new Guid(businessunits[0].Attributes["businessunitid"].ToString()));

cn.CrmService.Create(busunit);

Now obviously not the cleanest code but it does show you how easy it is to create a business unit.  If I was going to be more elegant about this code, I would be evaluating the parent unit on some additional criteria in my code and not simply be taking the first one that comes down.

Interestingly enough, when you run this code a second time, the primary business unit (the parent) now comes down with 9 attributes, whereas the one that I created has 17, so that could be an interesting keying off point as well.

More to dig into.

Do you still Customize the Default Solution?

Since the introduction of the solution framework in CRM 2011 (and now Dynamics365), I have not customized the default solution and find no value in doing so going forward.

Apart from their deployment and product shipping functionality, solutions provide a container where I can specifically look at what I am customizing and am working on as it pertains to my own entities.  Whether it is an unmanaged solution in Production or Development (hopefully not in Production), at the very least I have a container that takes me two minutes to create that nicely encapsulates all the changes I have made.

With the Default Solution, I see the world, everything that is in it and everything that is a part of it.  If I were to step away from this solution for a month or two and then come back to it, I would have to think hard about what I had modified and where.

And this is problem the worst part about the default solution is that it allows these changes to be introduced into a Production environment without anyone but that Administrator knowing what, when and where the change was made.  I’ve been in a few environments where we have worked on a solution, tested it and stamped it – only to have users complain that they are missing functionality from the latest release because there was a conflict with the default solution.

Even as a single developer on a small Dynamics system; take the time, plan for the growth of your solution and encapsulate your code into unmanaged solution at the very least.

You’ll be that much happier for it when your system starts to scale and grow.

 

 

 

 

Default Solution and Publisher Ids

In writing my last post on Creating your own Dynamics Publisher, I stumbled across the below information on the default solution and publisher Ids within Dynamics.

Both, the default solution and publisher are the same Guids across all Dynamics environments.

DefaultPublisherId  – {d21aab71-79e7-11dd-8874-00188b01e34f}

Furthermore, you can access the Default Solution Id (consistent across all environments).

DefaultSolutionId – {FD140AAF-4DF4-11DD-BD17-0019B9312238}

I did a quick validation between an on-premise CRM 2015 tenant and my online Dynamics instance and both lined up.

Reference: https://msdn.microsoft.com/en-us/library/gg328257.aspx

Understanding Publishers with Dynamics

A Publisher in Dynamics is the entity by which your solutions are deployed to Dynamics CRM.

No publisher means no solution being deployed.

In any Dynamics install, there is always a Default Publisher which you can use across your solutions (if you like) but exists as the publisher for customizations made to the base system.

Creating a publisher can be accomplished by simply going to Settings >> Customizations >> Publishers and creating your own publisher.

But that’s pretty boring, so we’re going to create one using code.

Creating your Publisher

Once you initialized a connection to Dynamics, put together a little console app and use the following code to create your own Publisher that can be used for deploying your own solutions.

 Entity crmPublisher = new Entity("publisher");
 crmPublisher["uniquename"] = "ForgottenCoder";
 crmPublisher["friendlyname"] = "Forgotten Coder";
 crmPublisher["supportingwebsiteurl"] = "www.forgottencoder.com";
 crmPublisher["customizationprefix"] = "fgc";
 crmPublisher["emailaddress"] = "emailaddress@emailme.com";
 crmPublisher["description"] = "This publisher is used to create all customizations by Forgotten Coder.";
 crmPublisher["customizationoptionvalueprefix"] = Convert.ToInt32("59999");

PublisherId = CrmService.Create(crmPublisher);

(Where CrmService is the IOrganizationService reference to my connection object.)

Run your code and you should have a newly created Publisher in Dynamics.

1_Publisher.PNG

Some Publisher Specifics

Some important to pieces to understand with publishers (as they pertain to your solutions), the prefix is very important as all objects created within your solution will be prefixed with this prefix.  Also, the Option Value Prefix indicates what number your option set will start from.

2_publisher.PNG

It’s important to note that Publishers and Solutions are not 1-to-1, you can have one publisher deploy many solutions but a solution can only have one publisher.

Searching for your Publisher

If you want to get fancy, you can do a lookup on startup of your application to see if your publisher exists and if so, go grab it’s PublisherId (you’re going to need it for your solution deployment) and store it in memory before deploying your solution.

QueryExpression pubQuery = new QueryExpression
 {
 EntityName = "publisher",
 ColumnSet = new ColumnSet("publisherid"),
 Criteria = new FilterExpression()
 };

pubQuery.Criteria.AddCondition("uniquename", ConditionOperator.Equal, "ForgottenCoder");
 EntityCollection results = CrmService.RetrieveMultiple(pubQuery);

3_publisher

Note: The above code snippet was modified from the Microsoft sample “Solutions” project shipped with the Dynamics SDK.