基于EF4.1的异构数据库访问组件(三)
接上一篇
基于EF4.1的异构数据库访问组件(二)中已完成了该组件的核心部分:
- IDbContextStorage – DbContext仓库
- IDbContextBuilder - DbContext动态组建器
- IDbContextManager – DbContext管理器
接下来,向大家介绍一下第一篇所说的,给上层提供统一的持久数据接口。
IRepository<T>
IRepository<T>就是需要提供给上层的统一数据持久接口,这里大家可以找到很多的例子,不多说,直接上类图:
上图中有以下几个主要部分:
- IRepository<T> - 数据持久接口
- SortOrder枚举 - 排序方式枚举
- IUnitOfWork - 工作单元接口
- UnitOfWork - 工作单元实现类
- EFRepository<T> - 数据持久实现基类
关于IUnitOfWork与IRepository<T>这块大家可以在园子里面找找文章,这里需要说明的是——我们怎样去确定哪个业务对象属于哪个数据库呢,关键在于EFRepository<T>这个基类的构造函数中:
public EFRepository(string connectionStringName) { _connectionStringName = connectionStringName; } private DbContext DbContext { get { if (_context == null) { if (string.IsNullOrEmpty(_connectionStringName)) throw new Exception("实例化数据持久化类时,未对_connectionStringName进行赋值μ"); _context = DbContextManager.CurrentByKey(_connectionStringName); } return _context; } }
PagedList<T>分页
在IRepository<T>中,我们提供了获取数据分页的方法。我采用的方法是使用PagedList<T>容器及扩展方法来实现的,EFRepository<T>的实现代码:
/// <summary> /// 根据条件及排序字段获取分页列表 /// </summary> public PagedList<T> GetPagedList(Expression<Func<T, bool>> predicate, string orderBy, SortOrder sortOrder, int pageIndex, int pageSize) { return DbContext.Set<T>().Where(predicate) .OrderBy(orderBy, sortOrder) .ToPagedList(pageIndex, pageSize); }下面来看看PagedList<T>及扩展方法ToPagedList
public class PagedList<T> : List<T> { public PagedList(IList<T> items,int pageIndex,int pageSize) { PageSize = pageSize; TotalItemCount = items.Count; TotalPageCount = (int)Math.Ceiling(TotalItemCount / (double)PageSize); CurrentPageIndex = pageIndex; StartRecordIndex=(CurrentPageIndex - 1) * PageSize + 1; EndRecordIndex = TotalItemCount > pageIndex * pageSize ? pageIndex * pageSize : TotalItemCount; for (int i = StartRecordIndex-1; i < EndRecordIndex;i++ ) { Add(items[i]); } } public PagedList(IEnumerable<T> items, int pageIndex, int pageSize, int totalItemCount) { AddRange(items); TotalItemCount = totalItemCount; TotalPageCount = (int)Math.Ceiling(totalItemCount / (double)pageSize); CurrentPageIndex = pageIndex; PageSize = pageSize; StartRecordIndex = (pageIndex - 1) * pageSize + 1; EndRecordIndex = TotalItemCount > pageIndex * pageSize ? pageIndex * pageSize : totalItemCount; } public int CurrentPageIndex { get; set; } public int PageSize { get; set; } public int TotalItemCount { get; set; } public int TotalPageCount{get; private set;} public int StartRecordIndex{get; private set;} public int EndRecordIndex{get; private set;} }public static class PageLinqExtensions { public static PagedList<T> ToPagedList<T> ( this IQueryable<T> allItems, int pageIndex, int pageSize ) { if (pageIndex < 1) pageIndex = 1; var itemIndex = (pageIndex - 1) * pageSize; var pageOfItems = allItems.Skip(itemIndex).Take(pageSize); var totalItemCount = allItems.Count(); return new PagedList<T>(pageOfItems, pageIndex, pageSize, totalItemCount); } public static PagedList<T> ToPagedList<T> ( this IEnumerable<T> allItems, int pageIndex, int pageSize ) { if (pageIndex < 1) pageIndex = 1; var itemIndex = (pageIndex - 1) * pageSize; var pageOfItems = allItems.Skip(itemIndex).Take(pageSize); var totalItemCount = allItems.Count(); return new PagedList<T>(pageOfItems, pageIndex, pageSize, totalItemCount); } public static PagedList<T> ToPagedList<T> ( this IQueryable<T> allItems, int pageIndex, int pageSize, int totalCount ) { if (pageIndex < 1) pageIndex = 1; var totalItemCount = totalCount; return new PagedList<T>(allItems, pageIndex, pageSize, totalItemCount); } public static PagedList<T> ToPagedList<T> ( this IEnumerable<T> allItems, int pageIndex, int pageSize, int totalCount ) { if (pageIndex < 1) pageIndex = 1; var totalItemCount = totalCount; return new PagedList<T>(allItems, pageIndex, pageSize, totalItemCount); } }
关于排序
直接新增扩展方法OrderBy
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, SortOrder sortOrder) where T : class { var type = typeof(T); var property = type.GetProperty(propertyName); if (property == null) throw new ArgumentException("propertyName", "不?存?在ú"); var param = Expression.Parameter(type, "p"); Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property); var orderByExpression = Expression.Lambda(propertyAccessExpression, param); var methodName = sortOrder == SortOrder.Ascending ? "OrderBy" : "OrderByDescending"; var resultExp = Expression.Call(typeof(Queryable), methodName, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression)); return source.Provider.CreateQuery<T>(resultExp); }
多条件动态查询
参考:http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx
呵呵,差不多这个组件就是这样子了,我会把代码作一个整理放到Codeplex上面,到时有需要的朋友请关注,谢谢!
分类:
Entity Framework
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架