基于EF4.1的异构数据库访问组件(三)

接上一篇

基于EF4.1的异构数据库访问组件(二)中已完成了该组件的核心部分:

  • IDbContextStorage – DbContext仓库
  • IDbContextBuilder   - DbContext动态组建器
  • IDbContextManager – DbContext管理器

接下来,向大家介绍一下第一篇所说的,给上层提供统一的持久数据接口。

IRepository<T>

     IRepository<T>就是需要提供给上层的统一数据持久接口,这里大家可以找到很多的例子,不多说,直接上类图:

     ClassDiagram1

    上图中有以下几个主要部分:

  • 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上面,到时有需要的朋友请关注,谢谢!   

posted @ 2011-10-22 22:20  青砖绿树  阅读(3054)  评论(8编辑  收藏  举报