16

I am using the following code to update an entity.

Service.Update(_policy);

where policy is a class generated using CrmSvcUtil.exe

public partial class new_policy : Microsoft.Xrm.Sdk.Entity, System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged

I retrieve the policies using LINQ, then update one attribute (an EntityReference) and then attempt the update

When this code runs I get the following error message:

EntityState must be set to null, Created (for Create message) or Changed (for Update message)

There are other entities generated in the same way that I can update.

I tried

_policy.EntityState = EntityState.Changed

but then I get a message saying

The entity is read-only and the 'EntityState' property cannot be modified. Use the context to update the entity instead.

Does anyone know what is causing this?

ccellar
  • 10,326
  • 2
  • 38
  • 56
Neil
  • 2,659
  • 7
  • 35
  • 57

5 Answers5

21

You have to tell your crmContext (use appropriate name) what to do with the changes.

You should add crmContext.UpdateObject(contact); before crmContext.SaveChanges();

See also How to update a CRM 2011 Entity using LINQ in a Plugin?

Community
  • 1
  • 1
ccellar
  • 10,326
  • 2
  • 38
  • 56
11

To avoid the problem you can simply use update-helper-objects instead of using the retrieved record:

var policyUpdater = new Policy { Id = _policy.Id, FieldToUpdate = "newValue" };
service.Update(policyUpdater);

Note: Properties of the update-helper-object that aren't set are simply ignored. The update won't set the corresponding record fields to null

user764754
  • 3,865
  • 2
  • 39
  • 55
  • Thank you, this helped me today! – Dyrborg Sep 23 '15 at 15:35
  • 1
    Best answer here easily because 1) it is very straightforward and 2) it doesn't assume that the query went for only the relevant columns (otherwise you will be resubmitting columns that aren't changing, causing a nightmare if you are trying to read the audit history). – Joseph Duty Nov 30 '15 at 15:31
10

I had the same problem. I switched from using

context.Update(object) 

to

context.UpdateObject(object) 

and it worked.

KClough
  • 2,079
  • 2
  • 21
  • 29
2

This worked for me:

recordToUpdate.EntityState = EntityState.Changed;

(recordToUpdate is an Entity to be updated)

Charan Raju C R
  • 758
  • 5
  • 21
  • 43
  • 2
    The EntityState is read only (maybe new in 2013). You should use the context to updater the state instead. – Ryan Feb 09 '15 at 05:08
1

Turns out it was an issue with my linq query that was retrieving the entity in the first place. When I replaced this with a query expression it worked okay.

Time to brush up on my linq!

Neil
  • 2,659
  • 7
  • 35
  • 57
  • 1
    I also wanted to use LINQ, even switched my existing QueryExpressions to it, only to find out it doesn't work. This post is the only explanation I've found so far which says retrieving an entity via LINQ and then updating it is not allowed by design. LINQ is designed only for querying. http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/682a7be2-1c07-497e-8f58-cea55c298062/ – roadsunknown Feb 20 '12 at 19:24
  • 1
    Just a friendly advise, be careful with LINQ, it seems that the query is executed each time you're using the object you're fetching and not storing it in memory if you're not careful. (necroposting deluxe but it might help someone) – Rickard N Jun 09 '16 at 10:47