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

Advertisement

CRM 2011 – How to set OptionSetValue in a plugin

I was creating a new entity and trying to fill in the default values for it and then use the

serviceProxy.Create method to add the new entity.

one of the entities had an OptionSet as a business required.   I tried searching for this but couldn’t find much and in the end I managed to work it out myself.

When you set an OptionSetValue you need to create a new one.  One of the problems I had was I because I was using Early Binding the values are set as null, so I couldn’t work out what it should be by looking at an example.

OptionSetValue option = new OptionSetValue(143570000);

The important thing you need to consider is the value is the value on the optionSet and its not very likely to be 1, 2, 3.  If you have created the optionSet yourself the default values are 140000000 or something huge like that.

I had to look on the form to find the value but then once you have made the new option set you can either add it directly to the entity

newCan.hosk_ContactPreference = option;

or if you are using the Entity you need to add it as an attribute

Entity ent = new Entity();

ent.Attributes.Add(“hosk_contactpreference”, option);