今日后开启进阶模式!
谈到MVC与EntityFramework,则不得不说一说事务与仓储(Unit of work + Repository)。
仓储(Repository):领域对象集合。用于操作领域对象与数据库上下文(DbContext)的交互(在此不得不说一声,领域对象和数据库表对象还是有区别的。领域对象实际上是一组有业务关系的数据库对象的抽象。最简单的形式就是主表、关系表在同一个领域对象中进行定义。例如我们前几章看到的UserProfile,它即定义了用户信息,又定义了用户角色关系信息)。
事务(Transaction):多个业务处理有必然的顺序性、依赖性,则默认这些业务为一个原子操作。在这里我们使用工作单元,即Unit of work模式,来维护事务的原子性。
首先,先让我们构建仓储接口。为了更好的使用EntityFramework的延迟加载,所有查询集合的接口我们均使用IQueryable接口类型作为返回值。
1 1 /// <summary> 2 2 /// 基础仓储类型接口 3 3 /// 采用泛型类接口定义 4 4 /// </summary> 5 5 /// <typeparam name="T">泛型参数</typeparam> 6 6 public interface IRepository<T> : IDisposable where T : class 7 7 { 8 8 /// <summary> 9 9 /// 返回当前表的所有记录 10 10 /// </summary> 11 11 /// <returns>T</returns> 12 12 IQueryable<T> Entries(); 13 13 14 14 /// <summary> 15 15 /// 通过过滤条件进行查询 16 16 /// </summary> 17 17 /// <param name="predicate">过滤条件表达式</param> 18 18 /// <returns>T</returns> 19 19 IQueryable<T> Filter(Expression<Func<T, bool>> predicate); 20 20 21 21 /// <summary> 22 22 /// 通过过滤条件进行查询 23 23 /// </summary> 24 24 /// <param name="predicate">过滤条件表达式</param> 25 25 /// <param name="includes">需贪婪加载的属性名称</param> 26 26 /// <returns>IQueryable</returns> 27 27 IQueryable<T> Filter(Expression<Func<T, bool>> predicate, params string[] includes); 28 28 29 29 /// <summary> 30 30 /// 是否存在满足表达式的记录 31 31 /// </summary> 32 32 /// <param name="predicate">过滤条件表达式</param> 33 33 /// <returns>Boolean</returns> 34 34 bool Contains(Expression<Func<T, bool>> predicate); 35 35 36 36 /// <summary> 37 37 /// 按照数据库主键查询特定的实例 38 38 /// </summary> 39 39 /// <param name="keys">主键列表</param> 40 40 /// <returns>T</returns> 41 41 T Single(params object[] keys); 42 42 43 43 /// <summary> 44 44 /// 按照指定表达式查询特定的实例 45 45 /// </summary> 46 46 /// <param name="predicate">过滤条件表达式</param> 47 47 /// <returns>T</returns> 48 48 T FirstOrDefault(Expression<Func<T, bool>> predicate); 49 49 50 50 /// <summary> 51 51 /// 插入一条记录 52 52 /// </summary> 53 53 /// <param name="t">新实例</param> 54 54 /// <param name="submitImmediately">是否直接提交。默认false。</param> 55 55 /// <returns>T</returns> 56 56 T Create(T t, bool submitImmediately = false); 57 57 58 58 /// <summary> 59 59 /// 删除一行记录 60 60 /// </summary> 61 61 /// <param name="t">要删除的实例</param> 62 62 /// <param name="submitImmediately">是否直接提交。默认false。</param> 63 63 void Delete(T t, bool submitImmediately = false); 64 64 65 65 /// <summary> 66 66 /// 删除满足表达式的记录 67 67 /// </summary> 68 68 /// <param name="predicate">过滤条件表达式</param> 69 69 /// <param name="submitImmediately">是否直接提交。默认false。</param> 70 70 void Delete(Expression<Func<T, bool>> predicate, bool submitImmediately = false); 71 71 72 72 /// <summary> 73 73 /// 更新一条记录 74 74 /// </summary> 75 75 /// <param name="t">要更新的实例</param> 76 76 /// <param name="submitImmediately">是否直接提交。默认false。</param> 77 77 void Update(T t, bool submitImmediately = false); 78 78 79 79 /// <summary> 80 80 /// 获取当前实例的主键 81 81 /// </summary> 82 82 /// <param name="t">实例</param> 83 83 /// <returns>Object</returns> 84 84 object GetKeyValue(T t); 85 85 }