Save Detached Entity in Entity Framework 6

Save detached entity in Entity Framework 6

Yes, this is correct. This article describes various ways of adding and attaching entities, and it provides this example:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };
using (var context = new BloggingContext())
{
// The next step implicitly attaches the entity
context.Entry(existingBlog).State = EntityState.Modified;
// Do some more work...
context.SaveChanges();
}

Since EF doesn't know which properties are different from those in the database, it will update them all:

When you change the state to Modified all the properties of the entity will be marked as modified and all the property values will be sent to the database when SaveChanges is called.

To avoid this, you can set which properties are modified manually rather than setting the entire entity state:

using (var context = new BloggingContext())
{
var blog = context.Blogs.Find(1);
context.Entry(blog).Property(u => u.Name).IsModified = true;
// Use a string for the property name
context.Entry(blog).Property("Name").IsModified = true;
}

How do I detach objects in Entity Framework Code First?

If you want to detach existing object follow @Slauma's advice. If you want to load objects without tracking changes use:

var data = context.MyEntities.AsNoTracking().Where(...).ToList();

As mentioned in comment this will not completely detach entities. They are still attached and lazy loading works but entities are not tracked. This should be used for example if you want to load entity only to read data and you don't plan to modify them.

Entity Framework 6 - Detached entity prevent saving duplicate navigation properties

I am suspicious of this section of code.

currentElement.Id = loadedAlias.Id;
currentElement = loadedAlias; // this seems pointless
dbContext.Entry(loadedAlias).State = EntityState.Unchanged;

If you want the line in question to do something, I think you need to set entityNode.AliasEntities.ElementAt(i) to loadedAlias -- setting currentElement to loadedAlias is just overriding the local instance variable to point at loadedAlias and as such seems like pointless code -- you haven't informed the entity that one of its intended children should point to this instance with that line. Something like the following might prevent the issue?

for (int i = 0; i < entityNode.AliasEntities.Count; i++) {
var currentElement = entityNode.AliasEntities.ElementAt(i);
var loadedAlias = dbContext.Aliases.Local.
FirstOrDefault(x => x.Alias == currentElement.Alias);
if (loadedAlias != null) {
currentElement.Id = loadedAlias.Id;
entityNode.AliasEntities.ElementAt(i) = loadedAlias;
dbContext.Entry(loadedAlias).State = EntityState.Unchanged;
}
}

Add Detached object to EF 6

Don't set the Carrier property of LoadCarrier, but instead only set the CarrierId.
This is enough for EF to know that it has to set the foreign key to an existing record.

There are other ways to do this, but since the Carrier is detached, it is most likely better to keep it attached and not to pull it in in the first place. I imagine you are preloading the carriers untracked because they are kind of fixed.

Storing a complex detached object graph in EF6

I ended up using GraphDiff to solve this for me, and it works just great! This really should be built into EF, but untill it does, this is a great substitute.

To solve the example given in my question above, this will make sure that the detached graph gets saved properly (given I have a MainObject I want to save called main):

context.UpdateGraph(main, map =>map
.AssociatedCollection( m => m.SubObjects, with => with
.AssociatedCollection( s => s.SubSubObjects)
)
);

context.SaveChanges();

Reattaching a detached entity throws an exception

The architecture I'm using in my program is that the data access layer is abstracted from the application.

It looks like you are implementing these methods on the ArchiveEntry class itself. That is not an abstracted data access layer, and passing entities around to many short-lived contexts like this will get you into trouble.

Instead of giving the entity classes their own methods for managing persistence concerns, you should put that code into a class separate from the entity, and make sure that once an entity gets attached to a context, you keep using that same context until it gets disposed. Once the context is disposed, if you want to do another operation on the entity, you should retrieve it from a new context before trying to do any (attached) things with it.

Entity Framework - restoring navigation property after detaching entities

You can use LoadProperty method:

context.LoadProperty(customer, c => c.Orders, MergeOption.OverwriteChanges);



Related Topics



Leave a reply



Submit