1
votes

I have a Dynamics CRM plugin that creates multiple child records when a parent opportunity is created. The plugin is registered as a post-operation, running synchronously.

When I create each child record independently, everything works fine:

Entity entity = (Entity)context.InputParameters["Target"];

do
{
    var revenue = new Entity("new_opportunityrevenue");
    revenue["lor_opportunityid"] = new EntityReference("opportunity", entity.Id);

    // Create the child record - Works
    service.Create(revenue);

    currentYear++;
} while (currentYear <= lastYear);

However, if I switch to an ExecuteMultipleRequest, I get an error that the Opportunity id does not exist whenever it tries to create the records. This occurs on the first request, so no additional processing occurs.

Entity entity = (Entity)context.InputParameters["Target"];

var revenueRecords = new List<Entity>();

do
{
    var revenue = new Entity("new_opportunityrevenue");
    revenue["lor_opportunityid"] = new EntityReference("opportunity", entity.Id);

    revenueRecords.Add(revenue);

    currentYear++;
} while (currentYear <= lastYear);

// Create the request object
var request = new ExecuteMultipleRequest()
{
    Settings = new ExecuteMultipleSettings()
    {
        ContinueOnError = false,
        ReturnResponses = true
    },
    Requests = new OrganizationRequestCollection()
};

// Add a CreateRequest for each entity to the request collection
foreach(var entity in revenueRecords)
{
    var createRequest = new CreateRequest { Target = entity };
    request.Requests.Add(createRequest);
}

// Execute all the requests in the collection using a single method call - Fails
// Opportunity With Id = 4ea41651-538e-e711-8118-e0071b6ad141 Does Not Exist
var response = (ExecuteMultipleResponse)service.Execute(request);

Why would calling Create() multiple times work, while calling Execute() with a ExecuteMultipleRequest fail?

Edit

I'm using Dynamics CRM Online (8.2.1.344). Here's a view of the plugin trace log showing the value it's using as the Opportunity ID, along with the ID of the opportunity that's been created. Individual year trace messages are just in-memory object creation.

Matching Ids

2
Which version of CRM is it (8.0, 8.1, ... ) ? Also, try using context.PrimaryEntityId instead of going through Target and see if anything changes.Alex
We're on CRM Online (8.2). I'll try your suggestion to see if that makes any difference.Steve Platz
@Alex Using context.PrimaryEntityId vs.entity.Id made no difference.Steve Platz
What happens if you run it asynchronously?Aron
You are using same variable name 'entity' in 2 different places. Are you not getting any error?Arun Vinoth - MVP

2 Answers

3
votes

Based on this post, an ExecuteMultiple gets its own database transaction when running inside a plugin. If those transactions are not nested, I'd imagine that's why you'd get that error, because the opp creation would then be in its own transaction that has not been committed.

As a side note, is there any benefit you're wanting from running your creates inside an ExecuteMultiple? It's designed more for reducing auth time from multiple requests; inside a plugin there's really no perf to be gained by using it.

0
votes

In addition to Matt's excellent answer, you should try to change this variable name in code & see if error is gone.

Entity **entity** = (Entity)context.InputParameters["Target"];

.........

// Add a CreateRequest for each child entity to the request collection
foreach(var **childentity** in revenueRecords)
{
var createRequest = new CreateRequest { Target = **childentity** };
request.Requests.Add(createRequest);
}