CRM 2011 – When to Attach an entity to the OrganizationServiceContext

I have been writing some plugins in CRM 2011 and for each plugin I use I usually setup a class which does link querying.  To do this I pass the OrganisationServiceContext

In my plugin I create this

// Get a reference to the Organization service.

IOrganizationServiceFactory factory =

(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

IOrganizationService service = factory.CreateOrganizationService(context.UserId);

Microsoft.Xrm.Sdk.Client.OrganizationServiceContext orgContext =

new Microsoft.Xrm.Sdk.Client.OrganizationServiceContext(service);

I have now have my OrganizationServiceContext which I can use in my Linq queries

public IEnumerable<hosk_candidate> searchCandidateID(Microsoft.Xrm.Sdk.Client.OrganizationServiceContext orgContext, string candidateId)

{

try

{

IEnumerable<hosk_candidate> candidates = from c in orgContext.CreateQuery<hosk_candidate>()

where (c.hosk_CandidateHoskID.Contains(candidateId))

select c;

//hosk_candidate candidate = (hosk_candidate)this.returnOne(candidates);

return candidates;

}

catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>)

{

// You can handle an exception here or pass it back to the calling method.

throw;

}

}

I have class in between the Plugin and Linq query class which gets the results

IEnumerable<hosk_candidate> candidates = linqQueries.searchCandidateID(this.orgContext, searchString);

The reason I have done it like this is so I can easily test the code because it isn’t in the plugin class itself.  I can create the OrganisationServiceContext easily and then pass it to the code the same way as the plugin code does.

I have found out that this works slightly unusually with regards to updating the data.  When you use Linq queries it Tracks the changes you make, these are tracked by the Service Context.

What this means is if you run a Linq query which returns some data and you then want to update the entity you plugin passed you can’t just add the object.

Initially I was working with an entity, I would then

orgContext.UpdateObject(can);

orgContext.SaveChanges();

add my entity to Context and update and then save like above, this works fine as long as you haven’t been querying different values in your linq query.

I tried to add a different entity to be updated (a different entity than the entities returned by my Linq) query and I kept getting errors thrown up.

I then worked out that I had to attach the entity and then update and save the changes.

orgContext.Attach(can)

orgContext.UpdateObject(can);

orgContext.SaveChanges();

I am now in situation where I do a linq query and if the query doesn’t return any values then I do not need to attach the entity and can just update and save it but if the linq query returns some entities then I need to attach my entity

if (recordUpdate)

{

orgContext.Attach(can);

}

orgContext.UpdateObject(can);

orgContext.SaveChanges();

 if (can.statecode == null)
                    {

                        orgContext.AddObject(can);
                    }
                    else
                    {
                       orgContext.Attach(can);
                    }

                    orgContext.UpdateObject(can);
                   orgContext.SaveChanges();

This has taken me a while to work this out.   The reason for Linq query returning or not returning results is I am setting an ID on a candidate based on surname, firstname and a counter.  I need to search to see if there are any ID’s with that value and if there are then add one to the counter but if this candidate is the first then create it, which is the reason why sometimes the linq queries returns values (and turns on tracking) and sometimes it doesn’t (new ID).

It would have probably helped if I had read this article by Microsoft

Use the Organization Service Context Class

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s