0
votes

Trying to update a list of Incident records. The first one in the foreach updates, the next one throws an exception stating "the context is not currently tracking the incident entity". Is this the correct way to code this?

var openCases = (from o in xrmContext.IncidentSet
                    where o.StateCode == 0
                    select o).Take(5).ToList();

                foreach (var c in openCases)
                {   
                    var numDays = ((TimeSpan) (DateTime.Now - c.CreatedOn)).Days;
                    Console.WriteLine("case age: {0},  case number:{1}", numDays, c.TicketNumber);
                    c.new_caseage = numDays;
                    xrmContext.UpdateObject(c);
                    xrmContext.SaveChanges();
                }
3

3 Answers

1
votes

When you call SaveChanges() it, in addition to saving any modified entity records, detaches all entity records being tracked in the context. Therefore, the second time you call SaveChanges() the entity record is not being tracked and you receive the error.

You should move the xrmContext.SaveChanges(); line to be after the foreach loop.

           var openCases = (from o in xrmContext.IncidentSet
           where o.StateCode == 0
           select o).Take(5).ToList();

            foreach (var c in openCases)
            {   
                var numDays = ((TimeSpan) (DateTime.Now - c.CreatedOn)).Days;
                Console.WriteLine("case age: {0},  case number:{1}", numDays, c.TicketNumber);
                c.new_caseage = numDays;
                xrmContext.UpdateObject(c);
            }
            xrmContext.SaveChanges();
0
votes

All entities are detached by the OrganizationServiceContext after calling the SaveChanges method. To continue using the data context against previously retrieved entities, the entities need to be reattached.

However, the preference is to apply all modifications under a single call to SaveChanges, and then dispose the context, to avoid the need to reattach.

http://msdn.microsoft.com/en-us/library/gg695783.aspx

http://msdn.microsoft.com/en-us/library/gg334504.aspx#track_related

0
votes

A better way to do what your try to do is using the message ExecuteMultipleRequest, with it can configure how many record to process for every iteration (internal iteration)

var openCases = (from o in xrmContext.IncidentSet
                    where o.StateCode == 0
                    select o).Take(5).ToList();

var requestWithResults = new ExecuteMultipleRequest()
    {
        // Assign settings that define execution behavior: continue on error, return responses. 
        Settings = new ExecuteMultipleSettings()
        {
            ContinueOnError = false,
            ReturnResponses = true
        },
        // Create an empty organization request collection.
        Requests = new OrganizationRequestCollection()
    };

    foreach (var c in openCases)
    {   
        var numDays = ((TimeSpan) (DateTime.Now - c.CreatedOn)).Days;
        c.new_caseage = numDays;

        CreateRequest createRequest = new CreateRequest { Target = c };
        requestWithResults.Requests.Add(createRequest);
    }

  ExecuteMultipleResponse responseWithResults =
  (ExecuteMultipleResponse)_serviceProxy.Execute(requestWithResults);

Hope it helps