EF添加和附加实体对象的状态

来源:互联网 发布:圣火名尊盾牌进阶数据 编辑:程序博客网 时间:2024/05/18 06:18
原文摘自微软网站:http://msdn.microsoft.com/en-us/data/jj592676

This topic will cover how to add and attach entities to acontext and how Entity Framework processes these duringSaveChanges. Entity Framework takes care of tracking the state ofentities while they are connected to a context, but in disconnectedor N-Tier scenarios you can let EF know what state your entitiesshould be in. The techniques shown in this topic apply equally tomodels created with Code First and the EF Designer.

Entity states andSaveChanges
An entity can be in one of five states as defined by theEntityState enumeration. These states are:
Added: the entity is being tracked by the context butdoes not yet exist in the database
Unchanged: the entity is being tracked by the contextand exists in the database, and its property values have notchanged from the values in the database
Modified: the entity is being tracked by the contextand exists in the database, and some or all of its property valueshave been modified
Deleted: the entity is being tracked by the context andexists in the database, but has been marked for deletion from thedatabase the next time SaveChanges is called
Detached: the entity is not being tracked by thecontext
 
SaveChanges does different things for entities in differentstates:
Unchanged entities are not touched by SaveChanges. Updates arenot sent to the database for entities in the Unchanged state.
Added entities are inserted into the database and then becomeUnchanged when SaveChanges returns.
Modified entities are updated in the database and then becomeUnchanged when SaveChanges returns.
Deleted entities are deleted from the database and are thendetached from the context.
 
The following examples show ways in which the state of anentity or an entity graph can be changed.

Adding a new entity to thecontext
A new entity can be added to the context by calling the Addmethod on DbSet. This puts the entity into the Added state, meaningthat it will be inserted into the database the next time thatSaveChanges is called. For example:

using (var context = new BloggingContext())
{
    var blog = new Blog {Name = "ADO.NET Blog" };
   context.Blogs.Add(blog);
   context.SaveChanges();
}

Another way to add a new entity to the context is to changeits state to Added. For example:

using (var context = new BloggingContext())
{
    var blog = new Blog {Name = "ADO.NET Blog" };
   context.Entry(blog).State = EntityState.Added;
   context.SaveChanges();
}

Finally, you can add a new entity to the context by hooking itup to another entity that is already being tracked. This could beby adding the new entity to the collection navigation property ofanother entity or by setting a reference navigation property ofanother entity to point to the new entity. For example:

using (var context = new BloggingContext())
{
    // Add a new User bysetting a reference from a tracked Blog
    var blog =context.Blogs.Find(1);
    blog.Owner = new User {UserName = "johndoe1987" };

    // Add a new Post byadding to the collection of a tracked Blog
    var blog =context.Blogs.Find(2);
    blog.Posts.Add(new Post{ Name = "How to Add Entities" });

   context.SaveChanges();
}

Note that for all of these examples if the entity being addedhas references to other entities that are not yet tracked thenthese new entities will also be added to the context and will beinserted into the database the next time that SaveChanges iscalled.

Attaching an existing entityto the context
If you have an entity that you know already exists in thedatabase but which is not currently being tracked by the contextthen you can tell the context to track the entity using the Attachmethod on DbSet. The entity will be in the Unchanged state in thecontext. For example:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NETBlog" };
using (var context = new BloggingContext())
{
   context.Blogs.Attach(existingBlog);
    // Do some morework... 
   context.SaveChanges();
}

Note that no changes will be made to the database ifSaveChanges is called without doing any other manipulation of theattached entity. This is because the entity is in the Unchangedstate.

Another way to attach an existing entity to the context is tochange its state to Unchanged. For example:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NETBlog" };
using (var context = new BloggingContext())
{
   context.Entry(existingBlog).State = EntityState.Unchanged;
    // Do some morework... 
   context.SaveChanges();
}

Note that for both of these examples if the entity beingattached has references to other entities that are not yet trackedthen these new entities will also attached to the context in theUnchanged state.

Attaching an existing butmodified entity to the context
If you have an entity that you know already exists in thedatabase but to which changes may have been made then you can tellthe context to attach the entity and set its state to Modified. Forexample:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NETBlog" };
using (var context = new BloggingContext())
{
   context.Entry(existingBlog).State = EntityState.Modified;
    // Do some morework... 
   context.SaveChanges();
}

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

Note that if the entity being attached has references to otherentities that are not yet tracked, then these new entities willattached to the context in the Unchanged state—they will notautomatically be made Modified. If you have multiple entities thatneed to be marked Modified you should set the state for each ofthese entities individually.

Changing the state of atracked entity
You can change the state of an entity that is already beingtracked by setting the State property on its entry. Forexample:

var existingBlog = new Blog { BlogId = 1, Name = "ADO.NETBlog" };
using (var context = new BloggingContext())
{
   context.Blogs.Attach(existingBlog);
   context.Entry(existingBlog).State = EntityState.Unchanged;

    // Do some morework... 

   context.SaveChanges();
}

Note that calling Add or Attach for an entity that is alreadytracked can also be used to change the entity state. For example,calling Attach for an entity that is currently in the Added statewill change its state to Unchanged.

Insert or updatepattern
A common pattern for some applications is to either Add anentity as new (resulting in a database insert) or Attach an entityas existing and mark it as modified (resulting in a databaseupdate) depending on the value of the primary key. For example,when using database generated integer primary keys it is common totreat an entity with a zero key as new and an entity with anon-zero key as existing. This pattern can be achieved by settingthe entity state based on a check of the primary key value. Forexample:

public void InsertOrUpdate(Blog blog)
{
    using (var context = newBloggingContext())
    {
       context.Entry(blog).State = blog.BlogId == 0?
                             EntityState.Added :
                             EntityState.Modified;

       context.SaveChanges();
    }
}

Note that when you change the state to Modified all theproperties of the entity will be marked as modified and all theproperty values will be sent to the database when SaveChanges iscalled.
0 0
原创粉丝点击