参考链接:http://www.entityframeworktutorial.net/EntityFramework5/entity-framework5-introduction.aspx
Connected Mode
Context detects adding and deleting entity, when the operation is performed only on DbSet. If you perform add and delete entity on a separate collection or list, then it won't detect these changes.
使用dbset将会探测到更改信息并能更新到数据源:
var studentList = context.Students.ToList();
context.Students.Add(new Student() { StudentName = "New Student2" });
使用list是不能直接更新数据源:
studentList.Add(new Student() { StudentName = "New Student" });
性能考虑,不必将AutoDetectChangesEnabled一直设置为true,可在需要时显示调用:
if you only need to read the records(i.e.you won't write them back) you will gain a performance boost by turning of change tracking for your context:
yourDbContext.Configuration.AutoDetectChangesEnabled = false;
Do this before loading any entities. If you need to update the loaded records you can allways call
yourDbContext.ChangeTracker.DetectChanges(); before calling SaveChanges().
DisConnectedMode
DbSet.Add():
//disconnected entity graph
Student disconnectedStudent =newStudent() { StudentName ="New Student"}; disconnectedStudent.StudentAddress =newStudentAddress() { Address1 ="Address", City ="City1"};
using(var ctx =new SchoolDBEntities())
{
//add disconnected Student entity graph to new context instance - ctx
ctx.Students.Add(disconnectedStudent);// get DbEntityEntry instance to check the EntityState of specified entity
var studentEntry = ctx.Entry(disconnectedStudent);
var addressEntry = ctx.Entry(disconnectedStudent.StudentAddress);
Console.WriteLine("Student EntityState:{0}",studentEntry.State);
Console.WriteLine("StudentAddress EntityState: {0}",addressEntry.State);
}
如上代码将离线生成的disconnectedStudent实体添加到在线dbset中,并更新实体的State为Added,然后调用ctx.Savechanges()方法即可将添加的实体更新到数据源中。
DbSet.Attach():
Attach方法的使用与Add类似,区别是Attach方法不会将State更新为Added或者其他,需要通过DbContext.Entry(disconnectedEntity).state = EntityState.Added/Modified/Deleted/Unchanged方法手动修改添加的实体的状态。
DisconnectedInsert
DIsconnectedUpdate
离线更新数据步骤:
1.从数据库中获取已有的对象实体(关闭数据库连接);
2.在数据库连接生命周期之外修改实体的属性;
3.重新连接数据库,设置此对象实体的状态为Modified。
注意:EF要求所有表都要有主键,通过主键将离线更新的实体与数据库中实体建立对应关系,将离线实体更新后的属性更新到数据源。所以在更新数据时,不要更新主键,若强制更新主键,若存在更新后主键对应的对象,ef将会更新新主键对应的对象,而不是在第一步中获取的对象。若不存在更新后主键对应的对象,则抛出异常,记录不存在或者已被删除。
4.调用SaveChanges()保存更改
Student stud;
//1. Get student from DB
using(varctx =newSchoolDBEntities())
{ stud = ctx.Students.Where(s => s.StudentName =="New Student1").FirstOrDefault
();}
//2. change student name in disconnected mode (out of ctx scope)
if(stud !=null){ stud.StudentName ="Updated Student1";}
//save modified entity using new Context
using(vardbCtx =newSchoolDBEntities()){
//3. Mark entity as modified
dbCtx.Entry(stud).State = System.Data.Entity.EntityState.Modified;
//4. call SaveChanges
dbCtx.SaveChanges();}
EntityFrame注意事项
1.Understand that call to database made only when the actual records are required. all the operations are just used to make the query (SQL) so try to fetch only a piece of data rather then requesting a large number of records. Trim the fetch size as much as possible
2.Yes, not you should, you must use stored procedures and import them into your model and have function imports for them. You can also call them directly ExecuteStoreCommand(), ExecuteStoreQuery<>(). Sames goes for functions and views but EF has a really odd way of calling functions "SELECT dbo.blah(@id)".
3.EF performs slower when it has to populate an Entity with deep hierarchy. be extremely careful with entities with deep hierarchy .
4.Sometimes when you are requesting records and you are not required to modify them you should tell EF not to watch the property changes (AutoDetectChanges). that way record retrieval is much faster
5.Indexing of database is good but in case of EF it becomes very important. The columns you use for retrieval and sorting should be properly indexed.
6.When you model is large, VS2010/VS2012 Model designer gets real crazy. so break your model into medium sized models. There is a limitation that the Entities from different models cannot be shared even though they may be pointing to the same table in the database.
7.When you have to make changes in the same entity at different places, try to use the same entity by passing it and send the changes only once rather than each one fetching a fresh piece, makes changes and stores it (Real performance gain tip).
8.When you need the info in only one or two columns try not to fetch the full entity. you can either execute your sql directly or have a mini entity something. You may need to cache some frequently used data in your application also.
9.Transactions are slow. be careful with them.