2
\$\begingroup\$

I have a WCF service, which has a method for updating a EF entity. The update method works just fine but looks ugly. I think due to some EF design I have to manually set the change tracker state to Modified or Deleted or Added. The update method in the server side looks like this:

public Event UpdateEvent(Guid sessionID, Event _event)
{
    Session session = IFSHelperClass.CheckSession(sessionID);

    try
    {
         using (IFSDB ifsdb = new IFSDB())
         {
             ifsdb.Events.Attach(_event);
             ifsdb.ObjectStateManager.ChangeObjectState(_event, System.Data.EntityState.Modified);

             // mark the modified and added items
             // for the navigation property 'EventPersons'
             foreach (var p in _event.EventPersons)
             {
                if (p.ChangeTracker.State == IFSEntities.ObjectState.Added)
                    ifsdb.ObjectStateManager.ChangeObjectState(p, System.Data.EntityState.Added);

                 if (p.ChangeTracker.State == IFSEntities.ObjectState.Modified)
                    ifsdb.ObjectStateManager.ChangeObjectState(p, System.Data.EntityState.Modified);
             }

             // since the deleted items will not be available in the
             // navigation property, delete them manually from the
             // ChangeTracker object.
             if (_event.ChangeTracker.ObjectsRemovedFromCollectionProperties.Count > 0)
             {
                 var personsToDelete = _event.ChangeTracker.ObjectsRemovedFromCollectionProperties.Where(t => t.Key == "EventPersons").Select(t => t.Value)
                     .FirstOrDefault()
                     .ToList();

                foreach (EventPerson p in personsToDelete)
                {
                  ifsdb.EventPersons.Attach(p);
                  ifsdb.EventPersons.DeleteObject(p);
                }
            }

            // save all changes and accept them
            ifsdb.SaveChanges();
            _event.AcceptChanges();
            foreach (var p in _event.EventPersons)
                p.AcceptChanges();

            return _event;
          }
      }
      catch (Exception ex)
      {
          Logger.LogError("UpdateEvent()", ex.Message, ex.ToString(), session.User.UserID);
          throw ex;
      }
 }

As you can see, II iterate through the navigation property items to check for updates or deletes and mark them manually.

Is this the way? or am I doing something ugly here?

\$\endgroup\$

migrated from stackoverflow.com Jun 3 '13 at 12:18

This question came from our site for professional and enthusiast programmers.

3
\$\begingroup\$

You shouldn't expose entities in WCF service. Every change in entity will cause WCF webservice change and incompatibility for existing consumers. I would create decicated data transfer objects for WCF webservice and use library like Automapper to handle property mapping.

EF entities often contain various properties (example: creation date, creator info), that shouldn't be modified, but when you expose whole entities, you allow this, which in future may cause security issues.

Small example (without Automapper):

public class EventDTO 
{
    public int Id { get; set; }
    public DateTime EventDate { get; set; }
    public string Title { get; set; }
}

In webservice class:

public Event UpdateEvent(Guid sessionID, EventDTO eventDTO)
{
    using (IFSDB ifsdb = new IFSDB())
    {
        var event = ifsdb.Events.First(item => item.Id == eventDTO.Id);
        event.EventDate = eventDTO.EventDate;
        event.Title = eventDTO.Title;
        ifsdb.SaveChanges();
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.