一步一步学EF系列 【7、结合IOC ,Repository,UnitOfWork来完成框架的搭建】
前言
距离上一篇已经有段时间了,最近这段时间赶上新项目开发,一直没有时间来写。之前的几篇文章,主要把EF的基础都讲了一遍,这批文章就来个实战篇。
个人在学习过程中参考博客:
- Entity Framework技术系列
- EF-Code First(1):Repository,UnitOfWork,DbContext
Repository
在数据库系统中,对于数据层来说,所有的操作归根结底无非“C(增加)、R(读取)、U(修改)、D(删除)”这四种操作。四种操作当中,与与业务相关度最大的是读取操作,根据各种不同的业务需求提交不同的查询,其最终执行应该放到业务层面中去进行,而增加,修改,删除这三种操作较为通用,可以作为通用数据操作封装到Repository中。在Repository中,唯一的变化点就是各种不同的实体类型,既然是变化点就应该进行封装,这里使用泛型来封装这个变化点。
还要说明一下,每个操作方法都带有一个 isSave 可选参数,是为了单个实体操作的需要,免去了每次都要调用 context.SaveChanged()的麻烦。如果是进行多个实体的单元事务操作,就需要把这个参数设置为 false 。
这里面就是定义了一个实体的增删改查。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
/// <summary> /// 定义仓储模型中的数据标准操作 /// </summary> /// <typeparam name="TEntity">动态实体类型</typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> public interface IRepository<TEntity, in TKey> : IDependency where TEntity : EntityBase<TKey> { #region 属性 /// <summary> /// 获取 当前实体的查询数据集 /// </summary> IQueryable<TEntity> Entities { get ; } #endregion #region 公共方法 /// <summary> /// 插入实体记录 /// </summary> /// <param name="entity"> 实体对象 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> int Insert(TEntity entity, bool isSave = true ); /// <summary> /// 批量插入实体记录集合 /// </summary> /// <param name="entities"> 实体记录集合 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> int Insert(IEnumerable<TEntity> entities, bool isSave = true ); /// <summary> /// 删除指定编号的记录 /// </summary> /// <param name="id"> 实体记录编号 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> int Delete(TKey id, bool isSave = true ); /// <summary> /// 删除实体记录 /// </summary> /// <param name="entity"> 实体对象 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> int Delete(TEntity entity, bool isSave = true ); /// <summary> /// 删除实体记录集合 /// </summary> /// <param name="entities"> 实体记录集合 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> int Delete(IEnumerable<TEntity> entities, bool isSave = true ); /// <summary> /// 删除所有符合特定表达式的数据 /// </summary> /// <param name="predicate"> 查询条件谓语表达式 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> int Delete(Expression<Func<TEntity, bool >> predicate, bool isSave = true ); /// <summary> /// 更新实体记录 /// </summary> /// <param name="entity"> 实体对象 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> int Update(TEntity entity, bool isSave = true ); /// <summary> /// 更新实体记录集合 /// </summary> /// <param name="entity"> 实体对象 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> int Update(IEnumerable<TEntity> entitys, bool isSave = true ); /// <summary> /// 查找指定主键的实体记录 /// </summary> /// <param name="key"> 指定主键 </param> /// <returns> 符合编号的记录,不存在返回null </returns> TEntity GetByKey(TKey key); #endregion } |
Repository的通用实现如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
/// <summary> /// EntityFramework仓储操作基类 /// </summary> /// <typeparam name="TEntity">动态实体类型</typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> public abstract class EFRepositoryBase<TEntity, TKey> : IRepository<TEntity, TKey> where TEntity : EntityBase<TKey> { #region 属性 /// <summary> /// 获取 仓储上下文的实例 /// </summary> public IUnitOfWork UnitOfWork { get ; set ; } /// <summary> /// 获取 EntityFramework的数据仓储上下文 /// </summary> protected UnitOfWorkContextBase EFContext { get { if (UnitOfWork is UnitOfWorkContextBase) { return UnitOfWork as UnitOfWorkContextBase; } throw new DataAccessException( string .Format( "数据仓储上下文对象类型不正确,应为UnitOfWorkContextBase,实际为 {0}" , UnitOfWork.GetType().Name)); } } /// <summary> /// 获取 当前实体的查询数据集 /// </summary> public virtual IQueryable<TEntity> Entities { get { return EFContext.Set<TEntity, TKey>(); } } #endregion #region 公共方法 /// <summary> /// 插入实体记录 /// </summary> /// <param name="entity"> 实体对象 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> public virtual int Insert(TEntity entity, bool isSave = true ) { PublicHelper.CheckArgument(entity, "entity" ); EFContext.RegisterNew<TEntity, TKey>(entity); return isSave ? EFContext.Commit() : 0; } /// <summary> /// 批量插入实体记录集合 /// </summary> /// <param name="entities"> 实体记录集合 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> public virtual int Insert(IEnumerable<TEntity> entities, bool isSave = true ) { PublicHelper.CheckArgument(entities, "entities" ); EFContext.RegisterNew<TEntity, TKey>(entities); return isSave ? EFContext.Commit() : 0; } /// <summary> /// 删除指定编号的记录 /// </summary> /// <param name="id"> 实体记录编号 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> public virtual int Delete(TKey id, bool isSave = true ) { PublicHelper.CheckArgument(id, "id" ); TEntity entity = EFContext.Set<TEntity, TKey>().Find(id); return entity != null ? Delete(entity, isSave) : 0; } /// <summary> /// 删除实体记录 /// </summary> /// <param name="entity"> 实体对象 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> public virtual int Delete(TEntity entity, bool isSave = true ) { PublicHelper.CheckArgument(entity, "entity" ); EFContext.RegisterDeleted<TEntity, TKey>(entity); return isSave ? EFContext.Commit() : 0; } /// <summary> /// 删除实体记录集合 /// </summary> /// <param name="entities"> 实体记录集合 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> public virtual int Delete(IEnumerable<TEntity> entities, bool isSave = true ) { PublicHelper.CheckArgument(entities, "entities" ); EFContext.RegisterDeleted<TEntity, TKey>(entities); return isSave ? EFContext.Commit() : 0; } /// <summary> /// 删除所有符合特定表达式的数据 /// </summary> /// <param name="predicate"> 查询条件谓语表达式 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> public virtual int Delete(Expression<Func<TEntity, bool >> predicate, bool isSave = true ) { PublicHelper.CheckArgument(predicate, "predicate" ); List<TEntity> entities = EFContext.Set<TEntity, TKey>().Where(predicate).ToList(); return entities.Count > 0 ? Delete(entities, isSave) : 0; } /// <summary> /// 更新实体记录 /// </summary> /// <param name="entity"> 实体对象 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> public virtual int Update(TEntity entity, bool isSave = true ) { PublicHelper.CheckArgument(entity, "entity" ); EFContext.RegisterModified<TEntity, TKey>(entity); return isSave ? EFContext.Commit() : 0; } /// <summary> /// 批量注册一个更改的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entity"> 要注册的对象 </param> public virtual int Update(IEnumerable<TEntity> entities, bool isSave = true ) { PublicHelper.CheckArgument(entities, "entities" ); EFContext.RegisterModified<TEntity, TKey>(entities); return isSave ? EFContext.Commit() : 0; } /// <summary> /// 查找指定主键的实体记录 /// </summary> /// <param name="key"> 指定主键 </param> /// <returns> 符合编号的记录,不存在返回null </returns> public virtual TEntity GetByKey(TKey key) { PublicHelper.CheckArgument(key, "key" ); return EFContext.Set<TEntity, TKey>().Find(key); } #endregion } |
实现类中所有操作最终都是通过单元操作来提交的,关于单元操作,接下来。这里用到了IOC,不懂的可以看之前的文章
UnitOfWork
引入单元操作,主要是为了给各个实体维护一个共同的DbContext上下文对象,保证所有的操作都是在共同的上下文中进行的。EF的操作提交 context.SaveChanged() 默认就是事务性的,只要保证了当前的所有实体的操作都是在一个共同的上下文中进行的,就实现了事务操作了。
在业务层中,各个实体的增删改操作都是通过各个实体的Repository进行的,只需要提供一个提交保存的功能作为最后调用,即可保证当前的提交是事务性的。因此定义给业务层引用的单元操作接口如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
/// <summary> /// 业务单元操作接口 /// </summary> public interface IUnitOfWork : IDependency { #region 属性 /// <summary> /// 获取 当前单元操作是否已被提交 /// </summary> bool IsCommitted { get ; } #endregion #region 方法 /// <summary> /// 提交当前单元操作的结果 /// </summary> /// <param name="validateOnSaveEnabled">保存时是否自动验证跟踪实体</param> /// <returns></returns> int Commit( bool validateOnSaveEnabled = true ); /// <summary> /// 把当前单元操作回滚成未提交状态 /// </summary> void Rollback(); #endregion } |
在数据组件内部,数据操作最终都提交到一个与IUnitOfWork接口的实现类中进行操作,以保证各个实体的Repository与IUnitOfWork使用的是同一个DbContext上下文。定义数据单元操作接口如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
/// <summary> /// 数据单元操作接口 /// </summary> public interface IUnitOfWorkContext : IUnitOfWork, IDisposable { /// <summary> /// 注册一个新的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entity"> 要注册的对象 </param> void RegisterNew<TEntity, TKey>(TEntity entity) where TEntity : EntityBase<TKey>; /// <summary> /// 批量注册多个新的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entities"> 要注册的对象集合 </param> void RegisterNew<TEntity, TKey>(IEnumerable<TEntity> entities) where TEntity : EntityBase<TKey>; /// <summary> /// 注册一个更改的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entity"> 要注册的对象 </param> void RegisterModified<TEntity, TKey>(TEntity entity) where TEntity : EntityBase<TKey>; /// <summary> /// 注册一个删除的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entity"> 要注册的对象 </param> void RegisterDeleted<TEntity, TKey>(TEntity entity) where TEntity : EntityBase<TKey>; /// <summary> /// 批量注册多个删除的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entities"> 要注册的对象集合 </param> void RegisterDeleted<TEntity, TKey>(IEnumerable<TEntity> entities) where TEntity : EntityBase<TKey>; } |
在单元操作的实现基类中,定义一个只读的DbContext抽象属性,实际的DbContext上下文需要在实现类中进行重写赋值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
/// <summary> /// 单元操作实现基类 /// </summary> public abstract class UnitOfWorkContextBase : IUnitOfWorkContext { /// <summary> /// 获取 当前使用的数据访问上下文对象 /// </summary> protected abstract DbContext Context { get ; } /// <summary> /// 获取 当前单元操作是否已被提交 /// </summary> public bool IsCommitted { get ; private set ; } public DbContext DbContext { get { return Context; } } /// <summary> /// 提交当前单元操作的结果 /// </summary> /// <param name="validateOnSaveEnabled">保存时是否自动验证跟踪实体</param> /// <returns></returns> public int Commit( bool validateOnSaveEnabled = true ) { if (IsCommitted) { return 0; } try { int result = Context.SaveChanges(validateOnSaveEnabled); IsCommitted = true ; return result; } catch (DbUpdateException e) { throw ; } } /// <summary> /// 把当前单元操作回滚成未提交状态 /// </summary> public void Rollback() { IsCommitted = false ; } public void Dispose() { //if (!IsCommitted) //{ // Commit(); //} Context.Dispose(); } /// <summary> /// 为指定的类型返回 System.Data.Entity.DbSet,这将允许对上下文中的给定实体执行 CRUD 操作。 /// </summary> /// <typeparam name="TEntity"> 应为其返回一个集的实体类型。 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <returns> 给定实体类型的 System.Data.Entity.DbSet 实例。 </returns> public DbSet<TEntity> Set<TEntity, TKey>() where TEntity : EntityBase<TKey> { return Context.Set<TEntity>(); } /// <summary> /// 注册一个新的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entity"> 要注册的对象 </param> public void RegisterNew<TEntity, TKey>(TEntity entity) where TEntity : EntityBase<TKey> { EntityState state = Context.Entry(entity).State; if (state == EntityState.Detached) { Context.Entry(entity).State = EntityState.Added; } IsCommitted = false ; } /// <summary> /// 批量注册多个新的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entities"> 要注册的对象集合 </param> public void RegisterNew<TEntity, TKey>(IEnumerable<TEntity> entities) where TEntity : EntityBase<TKey> { try { //禁用自动发现功能 Context.Configuration.AutoDetectChangesEnabled = false ; foreach (TEntity entity in entities) { RegisterNew<TEntity, TKey>(entity); } } finally { Context.Configuration.AutoDetectChangesEnabled = true ; } } /// <summary> /// 注册一个更改的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entity"> 要注册的对象 </param> public void RegisterModified<TEntity, TKey>(TEntity entity) where TEntity : EntityBase<TKey> { Context.Update<TEntity, TKey>(entity); IsCommitted = false ; } /// <summary> /// 批量注册一个更改的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entity"> 要注册的对象 </param> public void RegisterModified<TEntity, TKey>(IEnumerable<TEntity> entities) where TEntity : EntityBase<TKey> { Context.Update<TEntity, TKey>(entities.ToArray()); IsCommitted = false ; } /// <summary> /// 注册一个删除的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entity"> 要注册的对象 </param> public void RegisterDeleted<TEntity, TKey>(TEntity entity) where TEntity : EntityBase<TKey> { Context.Entry(entity).State = EntityState.Deleted; IsCommitted = false ; } /// <summary> /// 批量注册多个删除的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entities"> 要注册的对象集合 </param> public void RegisterDeleted<TEntity, TKey>(IEnumerable<TEntity> entities) where TEntity : EntityBase<TKey> { try { Context.Configuration.AutoDetectChangesEnabled = false ; foreach (TEntity entity in entities) { RegisterDeleted<TEntity, TKey>(entity); } } finally { Context.Configuration.AutoDetectChangesEnabled = true ; } } } |
业务整合
首先看接口的定义 ,他需要继承仓储接口
1
2
3
4
|
public interface IUserService : IRepository<Models.User, int > { } |
实现类继承仓储的基类
1
2
3
4
5
6
7
8
9
|
/// <summary> /// 仓储操作层实现——登录记录信息 /// </summary> public partial class UserRepository : EFRepositoryBase<Models.User, int >, IUserService { } } |
主要看一下使用,这里使用的是属性注入,然后就可以调用了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
public class UserService : IDependency { public IUserService userService { get ; set ; } /// <summary> /// 获取 当前实体的查询数据集 /// </summary> public virtual IQueryable<Models.User> User { get { return userService.Entities; } } public Models.User GetByKey( int id) { try { } catch (Exception) { throw new BusinessException(); } return userService.GetByKey(id); } /// <summary> /// 批量插入实体记录集合 /// </summary> /// <param name="entities"> 实体记录集合 </param> /// <param name="isSave"> 是否执行保存 </param> /// <returns> 操作影响的行数 </returns> public int Insert(IEnumerable<Models.User> entities) { return userService.Insert(entities); } /// <summary> /// 注册一个更改的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entity"> 要注册的对象 </param> public int RegisterModified(Models.User entity) { return userService.Update(entity); } /// <summary> /// 注册一个更改的对象到仓储上下文中 /// </summary> /// <typeparam name="TEntity"> 要注册的类型 </typeparam> /// <typeparam name="TKey">实体主键类型</typeparam> /// <param name="entity"> 要注册的对象 </param> public int RegisterModified(IEnumerable<Models.User> entity) { return userService.Update(entity); } } |
前端页面 OK完成,。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public UserService userserver { get ; set ; } public ActionResult Index() { //Models.User user = userserver.GetByKey(1); //ViewBag.Name = user.UserName; //1、批量新增 //userserver.Insert(new List<Models.User> { // new Models.User() { UserName="张三",Password="123456" }, // new Models.User() { UserName="李四",Password="123456" } //}); // //2、普通更新 //Models.User user = userserver.User.Single(m => m.UserID == 1); //user.UserName = "张三1"; //// userserver.RegisterModified(user); //Models.User user1 = userserver.User.Single(m => m.UserID == 2); //user1.Password = "456789"; ////批量更新 //userserver.RegisterModified(new List<Models.User> //{ // user, user1}); return View(); } |
结束语
本文最难理解的就是这个思路,如果能看懂的肯定会发现不足的地方,后面也准备了一个升级篇。不懂的可以加入下面的QQ群进行交流,源代码也已经上传到群共享文件了。欢迎下载。
大家也可以加入QQ群进行交流(435498053)。
作者:STONE刘先生 出处:http://www.cnblogs.com/liupeng/
一步一步学EF系列 【7、结合IOC ,Repository,UnitOfWork来完成框架的搭建】的更多相关文章
- 一步一步学EF系列【6、IOC 之AutoFac】
前言 之前的前5篇作为EF方面的基础篇,后面我们将使用MVC+EF 并且使用IOC ,Repository,UnitOfWork,DbContext来整体来学习.因为后面要用到IOC,所以本篇先单独先 ...
- 一步一步学EF系列【4、升级篇 实体与数据库的映射】live writer真坑,第4次补发
前言 之前的几篇文章,被推荐到首页后,又被博客园下了,原因内容太少,那我要写多点呢,还是就按照这种频率进行写呢?本身我的意图这个系列就是想已最简单最容易理解的方式进行,每篇内容也不要太多,这样初学者容 ...
- 一步一步学EF系列【5、升级篇 实体与数据库的映射】live writer真坑,第4次补发
前言 之前的几篇文章,被推荐到首页后,又被博客园下了,原因内容太少,那我要写多点呢,还是就按照这种频率进行写呢?本身我的意图这个系列就是想已最简单最容易理解的方式进行,每篇内容也不要太多,这样初学者容 ...
- 一步一步学EF系列3【升级篇 实体与数据库的映射】
之前的三张为基础篇,如果不考虑架构问题,做一般的小程序,以足够用了.基本的增删改查也都有了.但是作为学习显然是不够的.通过之前三章的学习,有没有发现这样写有什么问题,有没有觉得繁琐的?可能有人会说,之 ...
- 一步一步学EF系列四【升级篇 实体与数据库的映射】
之前的三张为基础篇,如果不考虑架构问题,做一般的小程序,以足够用了.基本的增删改查也都有了.但是作为学习显然是不够的.通过之前三章的学习,有没有发现这样写有什么问题,有没有觉得繁琐的?可能有人会说,之 ...
- 一步一步学EF系列一【最简单的一个实例】
整个文章我都会用最简单,最容易让人理解的方式给大家分享和共同学习.(由于live Writer不靠谱 又得补发一篇) 一.安装 Install-Package EntityFramework 二.简单 ...
- 一步一步学EF系列2【最简单的一个实例】
整个文章我都会用最简单,最容易让人理解的方式给大家分享和共同学习.(由于live Writer不靠谱 又得补发一篇) 一.安装 Install-Package EntityFramework 二.简单 ...
- 一步一步学EF系列三【数据迁移】
我们每篇的内容都不多,所以希望在学习的过程中最后能亲自敲一下代码 这样更有利于掌握. 我们现在接着上篇的例子,我们现在给随便的表增加一个字段 CreateTime 创建日期 运行一下 看看会怎么样 修 ...
- 一步一步学EF系列1【Fluent API的方式来处理实体与数据表之间的映射关系】
EF里面的默认配置有两个方法,一个是用Data Annotations(在命名空间System.ComponentModel.DataAnnotations;),直接作用于类的属性上面,还有一个就是F ...
随机推荐
- Openjudge-NOI题库-旅行-数论
题目描述 Description 转眼毕业了,曾经朝夕相处的同学们不得不都各奔东西,大家都去了不同的城市开始新的生活.在各自城市居住了一段时间后,他们都感到了一些厌倦,想去看看其他人的生活究竟如何,于 ...
- ecstore在MySQL5.7下维护报错WARNING:512 @ ALTER IGNORE TABLE
ecstore在MySQL5.7下维护报错WARNING:512 @ ALTER IGNORE TABLE 打开 /app/base/lib/application/dbtable.php , 替换A ...
- 前端必知的ajax
简介 异步交互 此篇只介绍部分方法,想了解更多就猛戳这里 1. load( url, [data], [callback] ) :载入远程 HTML 文件代码并插入至 DOM 中. url (Stri ...
- PHP静态延迟绑定和普通静态效率简单对比
只是一个简单的小实验,对比了下 延迟绑定 和 非延迟的效率 延迟绑定主要就是使用 static 关键字来替代原来的 self ,但功能非常强大了 实验代码: class A { protected s ...
- css基础和心得(三)
OK!接下来我们分别说这些元素的意义.首先,什么是块级元素?在html中<div>,<p>,<h1>,<form>,<ul>和<li& ...
- 使用 voluptuous 校验数据
在 Python 中,我们经常需要对参数进行校验,这是我们有好多种方法,例如写很多 if 啊,或者写正则表达式啊等等,技巧高的人可以写得很巧妙,而技巧一般的人呢,可能会写得很冗长,例如我,经常就不能很 ...
- js得到当前页面的url信息方法
js得到当前页面的url信息方法:http://www.cnblogs.com/zuosong160522/p/5755615.html js获取url传递参数,js获取url?后面的参数:http: ...
- Egret 学习之 从HelloWorld项目开始 (二)
1,创建新项目HelloWorld ,可以在界面上点击文件->新建,也可以在命令行使用create: 2,src 目录,存放我们的代码.我们编写的代码都放在src目录下面. bin-debug ...
- tomcat改端口的一些问题
cmd运行netstat -anp查看端口使用情况,找到被占用端口的PID
- rhel7.2 yum
redhat 的更新包只对注册的用户生效,所以我们自己手动更改成CentOS 的更新包,CentOS几乎和redhat是一样的,所以无需担心软件包是否可安装,安装之后是否有问题. (前提是wget包已 ...