CloudEntity%E4%BD%BF%E7%94%A8%E6%89%8B%E5%86%8C_01 - applelikai/CloudEntity GitHub Wiki

第01章 CloudEntity简介

基本介绍

  1. CloudEntity是什么?
    CloudEntity是一种类似于微软的EntityFramework实体框架,我在这里强调下,是实体框架,并不仅仅是ORM框架
  2. 什么是实体框架,与ORM框架有什么区别?
    在这里,关于这个问题我不做更加深入的探讨,相信什么是ORM框架,能看到我的这个教程的都了解了,我只简单的告诉你们,实体框架ORM框架的一个分支,是一个非常实用,非常高效的一个分支;能称为ORM框架的有很多,但能被称为实体框架的就非常罕见了,除了微软的EntityFramework,还有就是微软更早的时候开发的Linq To Sql,以及开源社区基于此开发的Linq To DB,今天我介绍的CloudEntity就是其中之一。
  3. CloudEntity支持哪些数据库?
    目前支持Microsoft Sql ServerOracleMySQL(也支持其分支MariaDB,配置和MySQL是一样的)和Postgresql。当然,如果能熟练使用CloudEntity了,除了上面列出来的数据库以外,你可以让它支持所有能够通过ADO.Net访问的数据库。

使用演示

好了,废话不多说了,先直接上代码吧。

  • 简单查询演示:
    // 获取数据容器
    IDbContainer container = DbContainer.Get(_connectionString);
    // 构建角色查询数据源
    IDbQuery<Role> roles = container.CreateQuery<Role>()
        // 并设置只查询RoleId 和 RoleName(不设置会查询所有)
        .SetIncludeBy(r => new { r.RoleId, r.RoleName })
        // 设置进一步检索角色名称不为空的角色数据
        .SetIsNull(r => r.RoleName, false);
    // 遍历角色列表
    foreach (Role role in roles) 
    {
        Console.WriteLine("{0} {1}", role.RoleId, role.RoleName);
    }
    遍历角色列表时,也会打印出之前生成的查询sql,其执行结果如下:
    ================
        SELECT `role`.`RoleId`,
               `role`.`RoleName`
          FROM pingguo_blog.`Sys_Roles` `role`
         WHERE `role`.`RoleName` IS NOT NULL
    ================
    31dcceae-52be-421c-a368-b8113d40dad1 管理员
    
  • 关联查询演示:
    // 获取数据容器
    IDbContainer container = DbContainer.Get(_connectionString);
    // 构建角色查询数据源
    IDbQuery<Role> roles = container.CreateQuery<Role>()
        // 并设置只查询RoleId 和 RoleName
        .SetIncludeBy(r => new { r.RoleId, r.RoleName })
        // 设置进一步检索角色名称不为空的角色数据
        .SetIsNull(r => r.RoleName, false);
    // 构建用户查询数据源
    IDbQuery<User> users = container.CreateQuery<User>()
        // 并设置只查询UserId 和 UserName(不设置则查询所有)
        .SetIncludeBy(u => new { u.UserId, u.UserName })
        // 并按RoleId关联角色查询数据源
        .SetJoin(roles, u => u.Role, (u, r) => u.RoleId == r.RoleId)
        // 设置进一步检索在某时间段内录入的用户数据
        .SetBetween(u => u.CreatedTime, DateTime.Parse("2023/01/01"), DateTime.Now);
    // 打印用户列表
    Program.PrintUsers(users);
    打印用户列表时,同样也会打印出生成的查询sql,其执行结果如下:
    ================
        SELECT `user`.`UserId`,
               `user`.`UserName`,
               `role`.`RoleId`,
               `role`.`RoleName`
          FROM pingguo_blog.`Sys_Users` `user`
    INNER JOIN pingguo_blog.`Sys_Roles` `role`
            ON `user`.`RoleId` = `role`.`RoleId`
         WHERE `role`.`RoleName` IS NOT NULL
           AND `user`.`CreatedTime` BETWEEN @CreatedTime0 AND @CreatedTime1
    ================
    管理员 admin
    管理员 bob
    管理员 apple
    
  • 分页查询演示:
    /// <summary>
    /// 分页查询测试
    /// </summary>
    /// <param name="userName">用户名</param>
    /// <param name="pageIndex">当前页</param>
    /// <param name="pageSize">每页元素数量</param>
    private static void Query(string userName, int pageIndex, int pageSize)
    {
        // 获取数据容器
        IDbContainer container = DbContainer.Get(_connectionString);
        // 构建角色查询数据源
        IDbQuery<Role> roles = container.CreateQuery<Role>()
            // 并设置只查询RoleId 和 RoleName
            .SetIncludeBy(r => new { r.RoleId, r.RoleName })
            // 设置进一步检索角色名称不为空的角色数据
            .SetIsNull(r => r.RoleName, false)
            // 设置按排序时间倒序排序
            .SetSortBy(r => r.CreatedTime, true);
        // 构建用户查询数据源
        IDbQuery<User> users = container.CreateQuery<User>()
            // 并设置只查询UserId 和 UserName(不设置则查询所有)
            .SetIncludeBy(u => new { u.UserId, u.UserName })
            // 并按RoleId关联角色查询数据源
            .SetJoin(roles, u => u.Role, (u, r) => u.RoleId == r.RoleId)
            // 设置进一步检索在某时间段内录入的用户数据
            .SetBetween(u => u.CreatedTime, DateTime.Parse("2023/01/01"), DateTime.Now);
        // 若用户输入了用户名查询内容
        if (!string.IsNullOrEmpty(userName))
        {
            // 则设置进一步按用户名检索用户数据
            users.SetWhere(u => u.UserName.Contains(userName));
            // users.SetLike(u => u.UserName, $"%{userName}%");
        }
        // 进一步构建用户分页查询数据源
        IDbPagedQuery<User> pagedUsers = users.PagingByDescending(u => u.CreatedTime, pageSize, pageIndex);
        // 打印分页信息
        Console.WriteLine("总页数: {0}", pagedUsers.PageCount);
        Console.WriteLine("当前页:{0}", pagedUsers.PageIndex);
        Console.WriteLine("每页数据:{0}", pagedUsers.PageSize);
        // 打印用户列表
        Program.PrintUsers(pagedUsers);
    }
    /// <summary>
    /// 程序启动时执行的方法
    /// </summary>
    private static void Main()
    {
        // 分页查询测试(每页10条,查询第1页数据)
        Program.Query("a", 1, 10);
    }
    在打印总页数时,会先生成一条SQL查询下符合条件的总数量,打印用户列表时,才会真正去生成其分页查询的SQL去执行查询,其执行结果如下:
    ================
        SELECT COUNT(*)
          FROM pingguo_blog.`Sys_Users` `user`
    INNER JOIN pingguo_blog.`Sys_Roles` `role`
            ON `user`.`RoleId` = `role`.`RoleId`
         WHERE `role`.`RoleName` IS NOT NULL
           AND `user`.`CreatedTime` BETWEEN @CreatedTime0 AND @CreatedTime1
           AND `user`.`UserName` LIKE @userName0
    ================
    总页数: 1
    当前页:1
    每页数据:10
    ================
        SELECT `user`.`UserId`,
               `user`.`UserName`,
               `role`.`RoleId`,
               `role`.`RoleName`
          FROM pingguo_blog.`Sys_Users` `user`
    INNER JOIN pingguo_blog.`Sys_Roles` `role`
            ON `user`.`RoleId` = `role`.`RoleId`
         WHERE `role`.`RoleName` IS NOT NULL
           AND `user`.`CreatedTime` BETWEEN @CreatedTime0 AND @CreatedTime1
           AND `user`.`UserName` LIKE @userName0
      ORDER BY `user`.`CreatedTime` DESC
         LIMIT @SkipCount, @NextCount
    ================
    管理员 admin
    管理员 apple
    
  • 指定UPDATE演示:
    private static void SaveUser(User user)
    {
        // 获取数据容器
        IDbContainer container = DbContainer.Get(_connectionString);
        // 指定要更新的用户部分字段
        var model = new { user.UserName, user.RoleId };
        // 指定更新用户部分字段
        int count = container.List<User>().SetAll(model, u => u.UserId.Equals(user.UserId));
        // 打印更新数量
        Console.WriteLine("更新 {0} 条数据", count);
    }
    在更新用户信息时,也会打印出生成的UPDATE SQL,其执行结果如下:
    ================
    UPDATE pingguo_blog.`Sys_Users` `user`
       SET `UserName` = @UserName,
           `RoleId` = @RoleId
     WHERE `user`.`UserId` = @UserId0
    ================
    更新 1 条数据
    
  • 删除演示:
    private static void RemoveUser(string userId)
    {
        // 获取数据容器
        IDbContainer container = DbContainer.Get(_connectionString);
        // 删除用户(不加条件就是删除所有用户了)
        int count = container.List<User>().RemoveAll(u => u.UserId.Equals(userId));
        // 打印删除数量
        Console.WriteLine("删除 {0} 条数据", count);
    }
    在删除用户信息时,也会打印出生成的DELETE SQL,其执行结果如下:
    ================
    DELETE `user`
      FROM pingguo_blog.`Sys_Users` `user`
     WHERE `user`.`UserId` = @userId0
    ================
    删除 0 条数据
    
  • 事务演示:
    private static void RemoveRole(string roleId)
    {
        // 获取数据容器
        IDbContainer container = DbContainer.Get(_connectionString);
        // 由于删除角色时,需要连同角色下的用户一起删除,所以这里开始使用事务
        using (IDbExecutor executor = container.CreateExecutor())
        {
            // 删除角色
            executor.Operator<Role>().RemoveAll(r => r.RoleId.Equals(roleId));
            // 删除角色下所有的用户
            executor.Operator<User>().RemoveAll(u => u.RoleId.Equals(roleId));
            // 最后,提交(别忘了,这一步很重要,另外,出现异常会自动RollBack)
            executor.Commit();
        }
    }
    在删除时,会生成如下DELETE SQL,最后会提交修改,执行结果如下:
    ================
    DELETE `role`
      FROM pingguo_blog.`Sys_Roles` `role`
     WHERE `role`.`RoleId` = @roleId0
    ================
    ================
    DELETE `user`
      FROM pingguo_blog.`Sys_Users` `user`
     WHERE `user`.`RoleId` = @roleId0
    ================
    

结语

简介就到这里,上面的演示,如果看到本手册的你能接受上面演示的代码,并且能很快读懂一个大概,那么恭喜你,本手册介绍的实体框架CloudEntity很适合你做项目时使用,能读懂上面演示代码的朋友,想必之前对Linq都非常熟悉吧,你们其中有不少之前都用过Linq To SqlEntityFramework之类的实体框架吧,我猜上面的演示代码一定会给你们打开一个新领域的大门;没错,有很多朋友猜到了,上面的查询像Linq,但又不是Linq,的却如此,实体框架CloudEntity并没有选择完全基于Linq,准确的说,是基于Lambda表达式,是一种基于实体的条件表达式,在这里我不做更加深入的探讨,你们自己领会,下面的章节就开始正式介绍其具体的从零开始使用实体框架CloudEntity的过程。

⚠️ **GitHub.com Fallback** ⚠️