views:

1594

answers:

3

Hi,

I've just started using Entity Framework rather than my normal NHiberante to see how EF works and so far I'm having lots of problems but one in particular is detaching an object and keeping the related child objects.
I bought the O'Reilly Entity Framework book which tells you "yes entity framework by default doesn't keep the object graph when you detach" but it doesn't show how you how to keep the graph! Thanks O'Reilly thats really useful.

Anyway if anyone can help that would be great, code below:

        using (var creativeWorkshopEntities = new CreativeWorkshopEntities())
        {
            var q = from c in creativeWorkshopEntities.Job.Include("Files")
                    where c.Id == jobId
                    select c;

            var job = q.First();

            creativeWorkshopEntities.Detach(job);

            return job;
        }

Thanks!

Dan

+4  A: 

Try using a NoTracking query instead. That way the objects arenever attached, so you don't need to 'detach' which is when the graph is shredded:

i.e.

using (var creativeWorkshopEntities = new CreativeWorkshopEntities())        
{            
    creativeWorkshopEntities.Job.MergeOption = MergeOption.NoTracking;
    var q = from c in creativeWorkshopEntities.Job.Include("Files")
            where c.Id == jobId                    
            select c;            
    var job = q.First();            
    return job;
}

Hope this helps

Alex

(Program Manager Entity Framework Team)

Alex James
That's great thanks Alex MergeOption done the trick for but the problem is without a detach my update method doesn't work, anyway around this? using (var creativeWorkshopEntities = new CreativeWorkshopEntities()) { if (job.Id > 0) creativeWorkshopEntities.AttachUpdated(job); //Custom extensor method else creativeWorkshopEntities.AddToJob(job); creativeWorkshopEntities.SaveChanges(); }
You need to use ApplyPropertyChanges(...) passing in the updated entity. ApplyPropertyChanges(updated) copies values from the 'updated' entity onto the original entity. For this to work the 'original' entity must be in the context, either because you held onto a copy and attached it (recommended) or because you did a query to re-load it from the database.
Alex James
A: 

Hi Alex

Check out http://www.codeproject.com/KB/architecture/attachobjectgraph.aspx

This is an awesome solution and may help you out - be aware that the author has an updated version on his own blog too.

Paul

+1  A: 

use below code to keep related objects in memory.

  using (var creativeWorkshopEntities = new CreativeWorkshopEntities())
  {
                var q = from c in creativeWorkshopEntities.Job.Include("Files")
                        where c.Id == jobId
                        select c;

                var job = q.First();

                return (Job)Detach(job);
   }

  private Object Detach(Object object)
  {
            using (var stream = new MemoryStream())
             {
                var formatter = new BinaryFormatter();
                formatter.Serialize(stream, dbo);
                stream.Position = 0;
               return formatter.Deserialize(stream);
             }
   }
Venkat