22

While searching for the best practivies of performing CRUD operation via EF I noticed that it is highly recommended to use Attach() or Find() methods before updating an entity. It works well and according to EF documentation these methods fetch the entity to context that is quite clear for me. But the followind code confused me pretty much

public void Update(object entity)
{
    Record record = new Record() {
        id = 1,
        value = 5
    };
    using (SomeContext ctx = new SomeContext())
    {
        ctx.Entry(record).State = EntityState.Modified;
        ctx.SaveChanges();
    }
}

Assume we have a record with id = 1 in database. On this condition the code above will update the record (set the value to 5). The question is why it works? And then why should I use Attach()?. As far as I understand the record wasn't attached to context in any way. I read relevant chapters of this book and the tutorial but they use 2-query-approach. Also I surfed SO but didn't find answer on my question. Help me with explanation or some good matherials, please.

Vitalii Isaenko
  • 941
  • 1
  • 14
  • 37

1 Answers1

42

If you have an entity that you know already exists in the database but which is not currently being tracked by the context - which is true in your case - then you can tell the context to track the entity using the Attach method on DbSet. So in summary what Attach method does is track the entity in the context and change its state to Unchanged. When you modify a property after that, the tracking changes will change its state to Modified for you. In the case you expose above you are telling explicitly that state is Modified but also to attach the entity to your context. You can find a detailed explanation in this post.

When should you use Attach method?

When you have an entity that you know already exists in the database but want to make some changes:

var entity= new Entity{id=1};
context.YourDbSet.Attach(entity); 

// Do some change...  
entity.value=5;

context.SaveChanges(); 

This is the same:

 context.Entry(entity).State = EntityState.Unchanged; 

// Do some change... 
entity.value=5; 

context.SaveChanges(); 

When should you change entity's State to Modified explicitly?

When you have an entity that you know already exists in the database but the changes have already been made then. The same scenario of your example

hbulens
  • 1,872
  • 3
  • 24
  • 45
ocuenca
  • 38,548
  • 11
  • 89
  • 102
  • thank you, but why this record is currently tracked by the context? – Vitalii Isaenko Dec 07 '16 at 19:19
  • If the entity is currently tracked and you change some property, the entity's state should change to `Modified` due to the tracking change, but for that your entities should meet this [requirements](https://msdn.microsoft.com/en-us/library/dd468057(v=vs.100).aspx) – ocuenca Dec 07 '16 at 19:24
  • I read the chapter before and maybe really misunderstood something but the question is still here. If I follow the requirements do all entities are tracked autmatically? My example shows that newly added object is already someway tracked by the context, so why should I use `Attach()`? And why that new object is tracked? Thank you for explaining, maybe I dig too deep. – Vitalii Isaenko Dec 07 '16 at 19:42
  • 2
    @VitaliiIsaenko Why that new object is tracked? Because when you call `ctx.Entry(record)` the DbContext will automatically Find or Create your entity and Attach it to the context. – Vyrira Dec 07 '16 at 19:58
  • 2
    Exactly, you don't need to use `Attach` method in that scenario. – ocuenca Dec 07 '16 at 20:11
  • For saving a list of class objects, then can we do it without attaching. – Sujay Ghosh Dec 11 '20 at 08:09