EntityFramework

1.Entity Framework 基础

  1. DbContext:是EF中的一个类,可以理解为一个数据库对象的实例,是实体类与数据库之间的桥梁,在EF中,对数据库的操作都是通过DbContext来进行操作的。
    DbContext 主要负责以下:
    (1) EntitySet:DbConext 包含映射到数据库表的所有实体的实体集(DbSet
    (2) 查询(Querying)可以使用sql语句进行查询
    (3) 更改跟踪(Change Tracking) 跟踪实体在从数据库查询后发生的更改
    (4) 持久数据(Persisting Data) 根据实体的状态对数据库进行插入、更新、删除操作
    (5) 缓存(Caching)默认进行一级缓存,它存储在上下文类生命周期中已经被检索的实体
    (6) 管理管理(Manage Relationship) DbContext还使用DB-First或Model-First方法使用CSDL,MSL和SSDL或者使用Code-First方法使用流利的API来管理关系

创建EF框架的上下文,保证线程内唯一

1
2
3
4
5
6
7
8
9
10
11
public static DbContext GetCurrentDbContext()
{
//CallContext:是线程内部唯一的独用的数据槽(一块内存空间)
DbContext dbContext = CallContext.GetData("DbContext") as DbContext;
if (dbContext == null)
{
dbContext = new WorkFlow_ManagerEntities();
CallContext.SetData("DbContext", dbContext);
}
return dbContext;
}

(7) 对象实现(Object Materialization) 将原始表数据转换为实体对象

2.Entity有五种状态:

  • Added(增加) entity 将会被context跟踪,但是还没有新增到数据库。
  • Unchanged(未变动) entity 已经存在数据库并且会被context 跟踪,entity的属性值与数据库中一致,没有变动。
  • Modified(修改) entity 已经存在数据库并且会被context 跟踪,entity的属性值被修改了。
  • Deleted(删除) entity 已经存在数据库并且会被context 跟踪,但是已经被标记将在下一次SaveChanegs 的时候从数据库中删除。
  • Detached(分离的) entity不会被context跟踪。

3.当entity处于不同的状态时,SaveChange做出不同的动作:

  • Unchanged 状态下,将不会向数据库发送Update 指令
  • Added 将会在数据库中插入记录,返回之后便会Unchanged 状态。
  • Modified 将会在数据库中插入记录,返回之后便会Unchanged 状态。
  • Deleted 将会在数据库中删除记录,返回之后变为Detached 状态

4.EF 增删改查
(1) 新增实体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1.第一中写法
using (var context = new Context())
{
var blog = new Blog { Name = "ADO.NET Blog" };
context.Blogs.Add(blog);
context.SaveChanges();
}
2.第二种写法
using (var context = new Context())
{
var blog = new Blog { Name = "ADO.NET Blog" };
context.Entry(blog).State = EntityState.Added;
context.SaveChanges();
}
3.结合反射的写法
using (var context = new Context())
{
var t = typeof(Blog);
var obj = Activator.CreateInstance(t);
var property = t.GetProperty("name");//获取对应属性对象
property.SetValue(obj,"ADO.NET Blog" ,null);
context.Entry(obj).State = EntityState.Added;
context.SaveChanges();
}

(2)向上下文附加一个已存在的实体

如果你有一个已经在数据库中存在的,但是并未被现有的context跟踪的实体,你可以告诉context通过DbSet的Attach方案来跟踪这个entity。这个entity在context中将会被设置为未变动状态。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1.第一种写法
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };
using (var context = new BloggingContext())
{
context.Blogs.Attach(existingBlog);

// Do some more work...

context.SaveChanges();
}
【注意】如果没有对附加的entit进行任何其他的操作,当调用SaveChanges方法时,数据库将不会有任何修改。这是因为entity处于未变动状态。

2.第二种写法
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" };
using (var context = new BloggingContext())
{
context.Entry(existingBlog).State = EntityState.Unchanged;

// Do some more work...

context.SaveChanges();
}

(3) 在上下文中附加一个已存在、但修改的实体
如果你有一个已经在数据库中存在的,但是已经做了修改的entity,你应该告诉context附加这个entity并设置状态为修改的。例如:

1
2
3
4
5
6
7
8
9
10
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" }; 
using (var context = new BloggingContext())
{
context.Entry(existingBlog).State = EntityState.Modified;

// Do some more work...

context.SaveChanges();
}
当你变更状态为修改的,entity的所有属性将会被标记为修改的,并且当SaveChanges方法被调用时,所有属性值都会传递给数据库。

(4)变更被跟踪的实体状态
你可以通过设置State属性来变更被跟踪的entity状态,例如:

1
2
3
4
5
6
7
8
9
10
11
var existingBlog = new Blog { BlogId = 1, Name = "ADO.NET Blog" }; 
using (var context = new BloggingContext())
{
context.Blogs.Attach(existingBlog);
context.Entry(existingBlog).State = EntityState.Unchanged;

// Do some more work...

context.SaveChanges();
}
【注意】在已经被跟踪的entity上新增或附加一个新的entity也将会改变entity的状态。例如,在一个处于新增状态的entity上附加一个新的entity将会改变他们的状态为未修改

(5)更新实体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1.第一种写法
using (var context = new BloggingContext())
{
var blog = context.FirstOrDefault();
blog.Name ="test";
context.Entry(blog).State = EntityState.Modified; //可加可不加
context.SaveChanges();
}
2.结合反射
using (var context = new BloggingContext())
{
var blog = context.FirstOrDefault();
var t = blog.GetType();
var property = t.GetProperty("name");//获取对应属性对象
property.SetValue(blog,"ADO.NET Blog" ,null);
context.Entry(blog).State = EntityState.Modified; //可加可不加
context.SaveChanges();
}

###Done.

坚持记录世界,分享世界