zoukankan      html  css  js  c++  java
  • 使用EF构建企业级应用

    2012-04-19 10:38 by 谢中涞, 1330 visits, 收藏编辑

    本系列目录:

    使用EF构建企业级应用(一):主要讲数据库访问基类IRepository及Repository 的实现

    使用EF构建企业级应用(二):主要讲动态排序扩展的实现

    使用EF构建企业级应用(三):主要讲灵活的构建查询条件表达式Expression<Func<TEntity,bool>>.

    使用EF构建企业级应用(四):主要讲下在MVC环境中前端开发中如何邮箱的使用,及一个实例源码包

    在前面三篇文章中,我们大致的描述了使用EF如何方便的实现数据持久化,我们简要的回忆下都有那些关键的内容段

    • Repository基类的实现,
    • 查询条件Expression<Func<T,bool>>的构建
    • 排序扩展

    那么前端在使用MVC模式的时候,如何方便将我们前面所实现的衔接起来呢? 我们今天就来探讨一下这个问题.

    我们先来看看我们在实际项目中是如何使用的,如果你对这个写法有兴趣那再往下看(查询界面我们采用JqGrid来展示数据)

             /// <summary>
            /// 查询产品列表
            /// </summary>
            /// <returns></returns>
            public ActionResult GetProductList()
            {
                string json = string.Empty;
                if (WebRuntimes.LoginUser == null)
                    return Content(GetAlertMessageJson("会话已过期,请重新登录"));
                try
                {
                    //构件查询条件
                    var queryParam = GetQueryParam<Product, PgQueryProductExp>();

                    int total = 0;

                    //查询数据
                    var lst = SysServices.GetProductList(queryParam, out total);
                    
                    //将lst转化为jqgrid接受的json格式
                    json = JsonForJqgrid(lst, total, queryParam.PageSize, queryParam.PageIndex);
                }
                catch (Exception ex)
                {
                    Logger.Log(ELogType.Error, ex);
                    json = GetAlertMessageJson("查询失败!");
                }

                return Content(json);
            }

    也许你很快就发现了上述代码中有两个陌生的方法,构建查询条件及从数据库获取数据,我们分别来看一下这两个方法中都干了什么.

        • 首先我们来看看在控制器基类中的构建查询条件的这个方法定义:
    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
    /// <summary>
    /// 获取页面分页查询条件
    /// </summary>
    /// <typeparam name="TEntity">待查询的实体</typeparam>
    /// <typeparam name="TPgQueryExp">页面查询转化类型</typeparam>
    /// <returns></returns>
    protected EFQueryParam<TEntity> GetQueryParam<TEntity, TPgQueryExp>()
        where TEntity : class
        where TPgQueryExp : class, IEFQueryExpression<TEntity>, new()
    {
        string sidx = "Code";
        if (!string.IsNullOrEmpty(Request.QueryString["sidx"]))
        {
            sidx = Request.QueryString["sidx"].ToString();
        }
        bool isSordAsc = false;
        if (!string.IsNullOrEmpty(Request.QueryString["sord"]))
        {
            if (Request.QueryString["sord"].ToString() == "asc")
            {
                isSordAsc = true;
            }
        }
        int pageSize = System.Convert.ToInt32(Request.QueryString["rows"]);
        int pageIndex = System.Convert.ToInt32(Request.QueryString["page"]) - 1;
     
        IEFQueryExpression<TEntity> exp = null;
        if (!string.IsNullOrEmpty(Request["d"]))
        {
            try
            {
                exp = GetObjectOfJson<TPgQueryExp>(Microsoft.JScript.GlobalObject.unescape(Request["d"]));
            }
            catch
            { }
        }
        if (exp == null)
            exp = new TPgQueryExp();
     
        EFQueryParam<TEntity> ret = new EFQueryParam<TEntity>(exp, sidx, isSordAsc, pageIndex, pageSize);
        return ret;
    }
    1
    然后我们来看一下,代码中有个陌生的对象PgQueryProductExp,那么他又做了什么呢?也许你已经猜到了,这个就是页面查询转化条件的,来简要的看一下是如何定义的

    /// <summary>
        /// 页面查询产品条件
        /// </summary>
        public class PgQueryProductExp : IEFQueryExpression<Product>
        {
            public string Code { get; set; }
            public string Name { get; set; }
            public string Specification { get; set; }
            public Guid CategoryId { get; set; }
            public int EnableFlag { get; set; }

            public PgQueryProductExp()
            {
                EnableFlag = 1;
            }

            public Expression<Func<Product, bool>> GetExpression()
            {

                var exp = EFExpression<Product>.CreateSignleLogic(ELogicType.And)
                    .Like(o => o.Code, Code)
                    .Like(o => o.Name, Name)
                    .Like(o => o.Specification, Specification);
                if (CategoryId != Guid.Empty)
                    exp = exp.Equal(o => o.CategoryId, CategoryId);

                //条件中是否需要判断是否有效?
                if (EnableFlag > -1)
                {
                    exp = exp.Equal(o => o.IsEnabled, (EnableFlag == 1));
                }

                return exp.GetExpression();
            }

    1
    其次我们来看一下在SysService 这个服务层中,我们是如何实现查询的

    /// <summary>
           /// 查询获取产品数据
           /// </summary>
           /// <param name="queryParam">查询参数</param>
           /// <param name="total">返回符合条件的记录总数</param>
           /// <returns></returns>
           public IList<Product> GetProductList(EFQueryParam<Product> queryParam, out int total)
           {
               total = 0;
               IList<Product> lst = null;
               using (var repository = new Repository<Product>())
               {
                   lst = repository.Include(o => o.ProductCategory).Get(queryParam, out total).ToList();
               }
               if (lst != null)
                   lst = lst.Select(o => o.GetJsonEntity()).ToList();
               return lst;
           }

     

    OK,这个就是一个完整的使用流程,貌似是很简单的吧,不过细心的你也许已经发现了,我们在使用查询的时候,貌似参查询条件数并不是使用的在上一篇文章中的Expression<Func<T,bool>> 模式.而是使用这个EFQueryParam<T>类型.没错,我们在使用的时候,很多兄弟说,这个查询方法的参数太多了,要求封装一下,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
    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
    /// <summary>
        /// 封装查询参数
        /// </summary>
        /// <typeparam name="TExpression">参数类型</typeparam>
        public abstract class QueryParam<TExpression>
        {
            /// <summary>
            /// 查询条件
            /// </summary>
            public TExpression Expression { get; set; }
     
            /// <summary>
            /// 排序字段
            /// </summary>
            public string OrderPropertyName { get; set; }
     
            /// <summary>
            /// 是否是升序排序,为false时则对OrderPropertyName采取降序排序
            /// </summary>
            public bool IsAscSort { get; set; }
     
            /// <summary>
            /// 分页查询,查询第几页
            /// </summary>
            public int PageIndex { get; set; }
     
            /// <summary>
            /// 分页查询,每页显示记录数
            /// </summary>
            public int PageSize { get; set; }
     
            /// <summary>
            /// 指示是否是分页查询
            /// </summary>
            public bool IsPagingQuery { get { return PageSize > 0; } }
     
        }
        /// <summary>
        /// EF 实现的 QueryParam
        /// </summary>
        /// <typeparam name="TEntity">条件关联实体类型</typeparam>
        public class EFQueryParam<TEntity> : QueryParam<Expression<Func<TEntity, bool>>> where TEntity : class
        {
            /// <summary>
            /// 实例化新的 EFQueryParam 实例
            /// </summary>
            /// <param name="exp">查询条件</param>
            /// <param name="orderPropertyName">排序属性字段名</param>
            /// <param name="isAscSort">是否是升序排序,false为降序排序</param>
            /// <param name="pageIndex">分页查询,查询第几页</param>
            /// <param name="pageSize">分页查询,每页显示记录数</param>
            public EFQueryParam(Expression<Func<TEntity, bool>> exp, string orderPropertyName,
                bool isAscSort, int pageIndex, int pageSize)
            {
                this.Expression = exp;
                this.OrderPropertyName = orderPropertyName;
                this.IsAscSort = isAscSort;
                this.PageIndex = pageIndex;
                this.PageSize = pageSize;
            }
     
            /// <summary>
            /// 实例化新的 EFQueryParam 实例
            /// </summary>
            /// <param name="exp">查询条件</param>
            /// <param name="orderPropertyName">排序属性字段名</param>
            /// <param name="isAscSort">是否是升序排序,false为降序排序</param>
            /// <param name="pageIndex">分页查询,查询第几页</param>
            /// <param name="pageSize">分页查询,每页显示记录数</param>
            public EFQueryParam(IEFQueryExpression<TEntity> exp, string orderPropertyName,
                bool isAscSort, int pageIndex, int pageSize) :
                this(exp.GetExpression(), orderPropertyName, isAscSort, pageIndex, pageSize)
            {
            }

     

    OK,大功告成.本系列也就写完了, 你可以通过这里下载完整的源码包去自己尝试.

    分类: .Net
  • 相关阅读:
    OpenGL搭建环境-VS2012【OpenGL】
    IOS内存约定-【ios】
    bootstrap下jQuery自动完成的样式调整-【jQuery】
    如何访问https的网站?-【httpclient】
    twitter typeahead控件使用经历
    grails服务端口冲突解决办法-【grails】
    jQuery中live函数的替代-【jQuery】
    如何自动设置网页中meta节点keywords属性-【SEO】
    如何在grails2.3.x中的fork模式下进行调试?-【grails】
    树的简介及Java实现
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2458612.html
Copyright © 2011-2022 走看看