söndag 17 november 2019

Creating objects with related objects in batch.


I have to admit that I’m slightly ashamed that this is sort of new to me. It probably isn’t a totally new, but I haven’t really used it and it is indeed a very powerful feature of the API in Dynamics 365, whatever it is called today.

There are quite a few questions regarding this.
Hug your related objects
Why isn’t this something that I have used before?
What are the benefits?

Will it work in ExecuteMultiple (is this even a question? I was wondering but whyyyy?)

This dawned a bit on me with the release of the October update from Microsoft. It might have itched a bit even earlier with the input of API throttling but with the October release the API calls was REALLY put in the flashlight since it will not only cause shortages in the use of the API when calls are rejected due to a very chatty world (5000 calls something per 5 minutes rolling time) but now the amount of API calls will cost money in the optimistic scenario and will just stop working completely in the very pessimistic and oh so unlikely scenario. We are still customers to a company that want to make money so there will most probably be a way.

So what part of the October release am I talking about? For many of you it’s obvious that it is the license part of the API calls that is the main focus here. In a “normal” instance of Dynamics-365-not-FinOps-or-similar, the instance will be limited to 20000 API calls per user per day (Enterprise license) and all app users will together share 100000 (100k, and also Enterprise license, at least one) calls per day. The app user calls is a bit unsure if they can be increased, but again Microsoft wants to make money so you will probably be able to do it.

Now since there will be some sort of counter the amount of calls in say an integration needs to be reduced. This is not only good for licensing reasons, but it will, probably, increase the performance as well. We all love the “performance issue meetings” so this might actually be a good thing after all.
I don’t know about you but when creating a set of objects which are linked together I have for the most part created the “main object” first, i.e. the Account, and after that looped through the to be linked objects, say contacts, and created them with the parentcustomerid-field set to the created account. On a good day the linked objects were created using ExecuteMultiple but not always, sometimes because I was lazy and copied the code from a plugin where the ExecuteMultiple wasn’t doing anything good anyway.

Ok Rickard, that was a good half page of loose talk, what are we looking at?


The star of this blog post is RelatedEntities. What on earth is that and when was it introduced, one might ask if one would like to know for how long one should have been ashamed. 

For the introduction, I truly have no clue but I’ve found a question which is pointing to the docs page (https://docs.microsoft.com/en-us/previous-versions/dynamicscrm-2016/developers-guide/gg326824(v=crm.8)?redirectedfrom=MSDN) which is from December 2014 so, maybe since CRM 2015 ish.
 
What is it then? 

This is a collection of entities which are related to the main entity and there is an object on the Entity class which is RelatedEntities. You add these as a key-value pair with a Relationship object as key (which is a slightly weird construct, it’s an object with a string field stating the name of the relationship, why not just have a string? Yes there are other things in there as well but come on…) and an EntityCollection of the related entities.
Creating an account with related contacts looks something like this:

Entity acc = new Entity("account");
            acc.Attributes.Add("name", "test1acc");
            EntityCollection accConts = new EntityCollection();
            Entity cont = new Entity("contact");
            cont.Attributes.Add("firstname", "conttest1f");
            cont.Attributes.Add("lastname", "conttest1l");
            Entity cont2 = new Entity("contact");
            cont2.Attributes.Add("firstname", "conttest2f");
            cont2.Attributes.Add("lastname", "conttest2l");
            accConts.Entities.Add(cont);
            accConts.Entities.Add(cont2);

            acc.RelatedEntities.Add(new KeyValuePair<Relationship, EntityCollection>(new Relationship("contact_customer_accounts"), accConts));
            client.Create(acc);

That’s it, very nice and oh so useable, not only because of the API things happening but it will make some calls quicker.

Back to the questions.

Why haven’t I used it? I just haven’t seen the benefit for some weird reason so I haven’t done my reading, I just have to stop with that. (and start reading)

What are the benefits? Read the article again 😊

Will it work with ExecuteMultiple, yes it can be used since the object created is really the account, or at least the main object. You just add the account to a CreateRequest and add that CreateRequest to the request list in the ExecuteMultiple object and PESTO you have a very nice way of reducing the API calls!


Happy coding.

Rickard Norström
Developer at CRM-Konsulterna
www.crmkonsulterna.se  

Inga kommentarer:

Skicka en kommentar