FieldIndex table(s) not updated when modifying a field programmatically

Topics: Customizing Orchard, Troubleshooting
Feb 4, 2016 at 10:09 PM
Edited Feb 4, 2016 at 10:43 PM

Using the Projections module, I created a Query with a filter like this:

User.MyCustomField is equal to '{Request.QueryString:myparameter}'
When I preview this projection (and add the appropriate querystring parameter), I get the expected results, which is a set of users where the MyCustomField value matches the myparameter querystring parameter.

When I use the Orchard Dashboard Users editor to modify the field value on a user, and then re-run the query preview, I get the expected results.

However, when I update the user content item's custom field value programmatically using the code below, and then re-run the query preview the query fails to find the newly updated value. This implies that my code to update the field is not correct, but what am I doing wrong?

It seems like the key issue is that my programmatic update of the content item is not triggering any refresh of the values in the special indexing tables used by the Projections module to execute the Query. How do I do this?

Code snippet, getting the current user and modifying a field value.
var contentItem = ((dynamic)_orchardServices.ContentManager.Get(_orchardServices.WorkContext.CurrentUser.Id));
var user = (dynamic)(contentItem.User);
user.MyCustomField.Value = "a new value"; 
_orchardServices.ContentManager.Publish(contentItem); // not required anyway?
Can anyone help explain what I need to do in order to ensure the query returns the correct results after the content item's custom field is updated? It seems as if the query results are cached or the content item is not being updated correctly.
Feb 4, 2016 at 11:32 PM
To be more specific, the problem is that my code snippet is resulting in the Orchard_Projections_StringFieldIndexRecord table to remain unchanged, even though I have attempted to modify the value of a string field.

How do we ensure the FieldIndex table(s) are properly updated when modifying a field value (and publishing a content item) programmatically?
Feb 4, 2016 at 11:44 PM
Edited Feb 4, 2016 at 11:45 PM
Ok, for those of you struggling with this, here's what resolved my issue.

This is closely related to the question on StackOverflow here:

Apparently the root cause is that the Publish handlers aren't fired unless the state of the content item is marked correctly. So I added one line of code to my code, to mark the content item as 'not published', illustrated below.
// mark as unpublished to ensure all the handlers are called, and the field indexes are updated
((ContentItem)contentItem).VersionRecord.Published = false;

Feb 5, 2016 at 11:16 PM
Although that definitely works, it is kind of a hack.
The correct way of doing this is by requesting a draft, updating it and then publishing that draft.
For example:
// Get a draft of the user content item. Notice the VersionOptions.DraftRequired argument on the next line:
var contentItem = ((dynamic)_orchardServices.ContentManager.Get(_orchardServices.WorkContext.CurrentUser.Id, VersionOptions.DraftRequired));

// Update some field of the user content item.
contentItem.User.MyCustomField.Value = "a new value"; 

// Publish the user content item.
Marked as answer by ayitey on 2/16/2016 at 4:25 AM
Feb 16, 2016 at 12:25 PM
Thanks, that is much better. I appreciate the tip. Is this documented anywhere? I would be happy to read that and keep it as a reference for future users here.