Two options are available in EF to let it know an object exists, “Attach” and “Add”, not sure when to use which.
“Add” as the verb suggests is for adding new objects to the EF context in order for them to be created/inserted in the database when calling “SaveChanges”. Without using “add” they float around as orphans as it were. The goal of “Add” is NOT to “tell EF about an object that already exists in the DB”. That is what “Attach” is used for: “Hey EF, you didn’t retrieve this object from the DB you lazy bum, but I am going to let you know that this object now exists as I programmatically instantiated it in custom code”.
So why on earth would you manually/programmatically instantiate an object that you could just as well have retrieved from the DB? Because its cheaper, and if you are like my wife you’re going to love saving money. If you’re the government you will make this pattern illegal. I quite often use ENUMs for keys of reference tables, like 1 = Male and 2 – Female. For example I have two Gender classes, one is part of the EF DbSet and the other just a plain old ENUM. In stead of making a DB call to get the object, if I need it on another object where it is a navigation property (like a Person class that has a navigation property of Gender), when a create a new Person object I don’t have to retrieve the Gender set from the DB, all I have to do is new up “Gender” and assign ENUM 1 to the ID to indicate a “Male”. Attach the new Gender object to the context, _dbSet.Attach(gender). Assign it to the Person object’s Gender property. EF will not try to insert it in the DB and sets the FK on the owning class (Person) relationship. Nice!
var male = new Gender();
male.ID = (int)Enums.Gender.Male;
_dbSet.Attach(male); //add to EF context indicating that it already exists in the DB
var person = new Person();
person.Gender = male;
_dbSet.Add(person); // insert into DB on SaveChanges
_context.SaveChanges(); //insert person but do nothing to the Gender table
Remember, behind the scenes when EF retrieves an object from the DB it calls “Attach” on its own context.
Cause-effect of SaveChanges:
- Attach: updates DB if DetectChanges in ChangeTracker observes a modification to the object.
- Add: insert into DB