zoukankan      html  css  js  c++  java
  • ORM之一:适合我的ORM

      一、常见开源ORM框架

      比喻:Kerosene ORM,DbLinq,Dapper,DynamicQuery,elinq,glinq,NPoco,Relinq,EF,ServiceStack.OrmLite,IQToolkit,对于这些框架,在单表查询这块支持的还蛮可以,但是对于多表查询的那种语法,我真有点接受不了,总感觉怪怪的,直观感觉就是没有了linq语法的那种美感,请忽视我的挑剔与自不量力,纯属个人喜好。

      例如:

    var cmd = link
       .From( x => x.Employees.As( x.Emp ) )
       .Join( x => x.Countries.As( x.Ctry ).On( x.Emp.CountryId == x.Ctry.Id ) )
       .Select( x => x.Emp.Id, x => x.Emp.FirstName, x => x.LastName )
       .Select( x => x.Ctry.Id, x => x.Ctry.Name )
       .OrderBy( x => x.Emp.Id );
    List<School> dataList = db.Sqlable()
       .Form("school", "s")
       .Join("student", "st", "st.id", "s.id", JoinType.INNER)
       .Join("student", "st2", "st2.id", "st.id", JoinType.LEFT).Where("s.id>100 and s.id<@id").SelectToList<School>("st.*", new { id = 1 });
     
    var joinQuery = new JoinSqlBuilder<User, User> ().
                    LeftJoin<User, Address> (x => x.Id, x => x.UserId).ToSql ();
     var testQuery = from c in db.Customers
                                from o in c.Orders
                                from d in o.Details
                                where o != exclude
                                select d;
    
    var test = testQuery.ToList();
    var query = from c in db.Customers
                            where c.CustomerID == "ALFKI"
                            join o in db.Orders on new {a = c.CustomerID, b = c.CustomerID} equals
                                new {a = o.CustomerID, b = o.CustomerID}
                            select new {c, o};

    等等。其次就是代码量相当庞大,阅读起来费力,虽然都是从接口、抽象类开始阅读,而且调试起来去理解它的代码需要耗费大量时间,且相关文档有些不完整。再次陷入了困境,前前后后也花了一些时间,于是静下心来想想,为何我不重新梳理下自己的计划了,原本是想在前人的基础上去修改修改就变成自己的了,但是核心代码还是别人的,自己没有掌握关键技术。看来这条路走不通了,只能靠自己了。   

      二、ORM所需具备的条件

      在日常开发中,如果是做业务逻辑开发一定会离不开单表增删改查、多表关联查询、存储过程、分页、聚合函数使用等。这里插播一段,因为我主要做后端开发以及框架搭建,平日最讨厌某某说,后台不就是增删改查吗?只要一听到类似的话语,我心中立即会有10万头草泥马向他奔去,鄙夷感顿生。但是马上会说,你怎么知道就只有增删改查了?哈哈。有点扯远了。不管是业务逻辑离不开这些,就一些框架组件也会将一些数据持久化,它们也离不开与数据库打交道。那么我觉得这个ORM必须具备如下条件:

      A、支持CRUD标准接口;

      B、支持多表联合查询接口,并且使用linq语法,但是一定不使用linq的那个join方式;

      C、支持聚合函数、支持分组以及hanving、支持存储过程调用、支持分页,支持sql语句,支持事务;

      D、支持部分常用C# 函数调用;

      E、支持与元数据进行映射的工具;

      F、能扩展oracle,mysql等主流数据库;

      如果能满足上述6个大条件,那么这个轮子基本上就满足日常开发中80%左右的场景了,那么快速开发也就不在话下了。

      

      三、适合我的ORM操作示例

      有了上面的基础,结合一下目前主流的ORM框架,那么就可以想象下ORM的部分使用示例了。

      A、单表增删改查

      Insert:

    Db<T>.Insert(实体对象);

      Delete:

    Db<T>.Delete(w => w.条件字段== 4);

      Update:

    Db<T>.Update(up => new 实体对象{需要修改字段= "xxxxxx" }, wh => wh.条件字段== 4);

      Select:

    Db<T>.Single(w => w.条件字段.Contains("@")); //单条记录
    Db<T>.Select(w => w.条件字段.Contains("@")); //多条记录

      B、多表联合查询

      join:

    var results = (from u in Db<T>.查询对象a
                      join ur in Db<T>.查询对象b on new
                      {
                          u = u.条件字段1,
                          a = u.条件字段2
                      } equals
                        new
                        {
                            u = ur.条件字段1,
                            a = ur.条件字段2
                        }
                      join r in Db<T>.查询对象c on ur.条件字段3 equals r.条件字段3
                     where u.条件字段4 == 1
                      orderby u.条件字段5
                     select new object  //可以匿名 select new
                     {
                        v= u.字段,
                        vv= u.字段,
                        vvv= u.字段,
                        vvvv= r.字段
                      }).设置表关联类型(类型Inner, 类型.left);

      分页:

    results.Page(1,1);

      C、存储过程

    var dbParameters = new DbParameterCollection
    {
      new DbParameter{DbType = DbType.Int32,Name = 输入参数名称,Value = 1,Direction = ParameterDirection.Input},
    new DbParameter{DbType = DbType.Int32,Name = 输出参数名称,Direction = ParameterDirection.Output }
    };
    
    var affectCount = Db.执行存储过程(存储过程名称, 存储过程参数); //这里是返回影响行数,还可以扩展返回ilist<T>集合,dataset对象
    
    var returnc = dbParameters[output参数名称].Value;

      D、执行sql语句

    var ds = Db.执行查询("select * from demoTable"); //还可以扩展返回ilist<T>集合,影响行数等
    foreach (DataRow row in ds.Tables[0].Rows) { Console.WriteLine(row[0]); }

      E、事务

    using (var 数据库对象提供者实例= Db.默认实例)
    {
        try
        {
          Begin(); //开始事务
    
           //to do...
    
          Commit(); //提交事务
        }
        catch (Exception)
        {
          Rollback(); //回滚事务
        }
    }

      F、多表联合查询分组

    var resultList = (from a in Db<T>.查询对象1
                                join b in Db<T>.查询对象1 on a.条件字段1 equals b.条件字段2
                      group new {对象a, 对象b} by new {对象a.字段}
                        into g
                      where g.Sum(m=>m.对象b.字段)>200
                      select new
                      {
                        userId= g.Key.对象a.字段,
       TotalScore
    = g.Max(b => b.对象b.字段) }).ToList();

      G、其他就不一一列举了,具体详见后续博文。

         

  • 相关阅读:
    EasyUI笔记(三)Window窗口
    EasyUI笔记(二)Layout布局
    从零构建Flink SQL计算平台
    从零构建Flink SQL计算平台
    Hystrix压测
    Java对象属性复制备忘
    Java垃圾回收手册翻译
    一次虚拟机升级和参数调整记录
    获取不同虚拟机参数的终极方法
    Dataset数据的XML持久化处理
  • 原文地址:https://www.cnblogs.com/wucj/p/4947337.html
Copyright © 2011-2022 走看看