XIKEW.COM - 实用教程 - 内置数据操作ORMX基础功能介绍 - 实用教程,ORM,NETCORE ORM,.NET,数据库管理 - ORMX是LinkCoreX内置的一套轻便的数据库操作框架,轻松简单的编码风格几乎不需要多少学习成本

内置数据操作ORMX基础功能介绍
LINKCORE NETCORE 框架 ORM 9/6/2024 8:34:42 PM 阅读:24

ORMX是LinkCoreX内置的一套轻便的数据库操作框架,轻松简单的编码风格几乎不需要多少学习成本 关键字:ORM,NETCORE ORM,.NET,数据库管理

[[toc]]

模型类 Model

User 模型类

ORMX支持根据模型类自动建表所以先在项目的 Model 目录下建一个 User.cs 的类

using LinkCore.Interface.ORMX;
using System;

namespace Demo.Model
{
    [ORMXTable(Name = "User", Prefix = "ORMX_")]
    class User
    {
        [ORMXColumn(IsPrimaryKey = true, Comment = "编号", Length = "50")]
        public string Id { get; set; }= Guid.NewGuid().ToString();

        [ORMXColumn(Comment = "创建时间")]
        public DateTime CreateTime { get; set; } = DateTime.Now;

        [ORMXColumn(Comment = "更新时间", AutoOnUpdate = true)]
        public DateTime? UpdateTime { get; set; }

        [ORMXColumn(Comment = "姓名")]
        public string Name { get; set; }

        [ORMXColumn(Comment = "性别")]
        public int Sex { get; set; }

        [ORMXColumn(Comment = "生日")]
        public DateTime? Birthday { get; set; }

        [ORMXColumn(Comment = "手机")]
        public string Mobile { get; set; }

        [ORMXColumn(Comment = "登录次数")]
        public int LoginCount { get; set; }
    }
}

::: warning 出于对项目后期运维的可控性考虑自动维护字段的功能没有开放,所以如果项目迭代过程中修改了模型的结构,需要手动维护数据库字段! :::

People 模型类

为了方便演示,我们再创建一个 People 模型类做备用

[ORMXTable(Name = "People", Prefix = "ORMX_")]
class People
{
    [ORMXColumn(IsPrimaryKey = true, Comment = "编号", Length = "50")]
    public string Id { get; set; } = Guid.NewGuid().ToString();

    [ORMXColumn(Comment = "创建时间")]
    public DateTime CreateTime { get; set; } = DateTime.Now;

    [ORMXColumn(Comment = "更新时间", AutoOnUpdate = true)]
    public DateTime? UpdateTime { get; set; }

    [ORMXColumn(Comment = "关联UserId", Length = "50")]
    public string UserId { get; set; }

    [ORMXColumn(Comment = "公司")]
    public string Company { get; set; }

    [ORMXColumn(Comment = "公司地址")]
    public string CompanyAddr { get; set; }

}

ORMXTable 表格特性

(((折叠==折叠)))using System;

namespace LinkCore.Interface.ORMX
{
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class ORMXTable : Attribute
    {
        /// <summary>
        /// 表明前缀
        /// </summary>
        public string Prefix { get; set; }
        /// <summary>
        /// 表名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 按时分表
        /// </summary>
        public bool DateGroup { get; set; }

        /// <summary>
        /// 按时分表格式yyyyMMdd HH:mm
        /// 不支持秒级分表
        /// </summary>
        public string DateGroupFormatString { get; set; }

        /// <summary>
        /// 自动建表开关
        /// </summary>
        public bool AutoCreate { get; set; } = true;
    }
}

ORMXColumn 字段特性

(((折叠==折叠)))using System;

namespace LinkCore.Interface.ORMX
{
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class ORMXColumn : Attribute
    {
        /// <summary>
        /// 字段名
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 主键
        /// </summary>
        public bool IsPrimaryKey { get; set; }

        /// <summary>
        /// 忽略映射
        /// </summary>
        public bool Ignore { get; set; }

        /// <summary>
        /// 类型
        /// </summary>
        public string Type { get; set; }

        /// <summary>
        /// 长度
        /// </summary>
        public string Length { get; set; }

        /// <summary>
        /// 是否能NULL
        /// </summary>
        public bool Nullable { get; set; }

        /// <summary>
        /// 默认值
        /// </summary>
        public string Default { get; set; }

        /// <summary>
        /// 非负数
        /// </summary>
        public bool UnSign { get; set; }

        /// <summary>
        /// 自增
        /// </summary>
        public bool AutoIncrement { get; set; }

        /// <summary>
        /// 时间自动更新
        /// </summary>
        public bool AutoOnUpdate { get; set; }

        /// <summary>
        /// 注释
        /// </summary>
        public string Comment { get; set; }

        /// <summary>
        /// 维护数据库功能,备注默认为空 ,空时不自动新增数据库(需手动维护,否则程序会报错)
        /// </summary>
        public string AddColumnRemark { get; set; }
    }

}

表格操作 Table

using LinkCore.Interface;
using LinkCore.Interface.ORMX;
using LinkCore.Interface.Router;
using System;

namespace DemoPlugin.V1
{
    public class ORMX : ApiController 
    {
        static private IEntity entity = IEntity.CreateMySQLEntity("server=127.0.0.1;port=3306;database=数据库;user=用户名;password=密码;");
        
        public IActionResult GetTest()
        {
            //推荐写法
            using (var table = entity.Table<Model.User>())
            {
                // ... 测试代码
            }
        }
    }
}

写入数据 Insert


table.Insert(new Model.User {
    Name = "测试",
    Sex = 0,
    Birthday = DateTime.Parse("1997-07-01"),
    Mobile = "",
    LoginCount = test
});

为方便测试,我们先创建一个路由类,之后函数无特殊说明都是基于这个路由类的。

以上代码通过访问 /DemoPlugin/V1/ORMX/Test 来激活测试

查询数据 FIND / FINDALL

// 获取单条数据
table.Find();

// 获取数据列表
table.FindAll();

::: warning 直接调用 FindAll 并不会存在性能问题,因为函数还支持两个参数

FindAll(int pageSize = 20, int pageNum = 1)

:::

查询大小 Max / Min

查询登录次数最多的数据

table.Where(m => m.Sex == 1).Max(x => x.LoginCount);

数据统计 Count / Sum / Avg

// 统计数据库性别值为1的总数量
table.Where(m => m.Sex == 1).Count();

// 统计登录次数
table.Where(m => m.Sex == 1).Sum(m => m.LoginCount);

// 统计登录平均值
table.Where(m => m.Sex == 1).Avg(m => m.LoginCount);

::: warning Max / Min / Count / Sum / Avg 五个函数都有第二个参数 asName 可以将统计后的结果指定一个名称 由于Count通常第一个参数也省略,可以使用

Count(asName: "CountName");

:::

更新数据 Update

// 按照对象更新,假设 userModel 是一个数据实例
table.Where(m => m.Id == "1").Update(userModel);

// 更新部分数据
table.Where(m => m.Id == "1")
.UpdateValue(
    m => m.Name.Equals("知时"),
    m => m.Sex.NumAdd(-1),
    m => m.Birthday.Equals(DateTime.Now),
    m => m.Mobile.Equals("15157787553")
);

::: tip NumAdd 函数可以在更新时对数字进行增减计算 :::

删除数据 Delete

table.Where(m => m.Id == 1).Delete();

筛选器 Filter

字段筛选 Column

table.Column(m => new[] { m.Name }).FindAll();

空值处理 Coalesce

::: tip 暂不支持 :::

查询条件 Where

逻辑等式

Where 是最常用的功能之一,使用也非常简单

// 获取男性数据列表
table.Where(m => m.Sex == 1).FindAll();

::: tip Where 的参数可以用 Lambda 表达式 m => bool 其中 m 就是 Table<Model.User> 泛类 Model.User 而返回 bool 值 :::

属性函数

除了使用逻辑等式外属性还支持一些方法

table.Where(m => m.Sex.Equals(1)).FindAll();

// Where In
table.Where(m => m.Sex.InList(1,2)).FindAll();
table.Where(m => m.Sex.NotInList(1,2)).FindAll();

// 模糊搜索 LIKE 
table.Where(m => m.Name.Contains("测试")).FindAll();
table.Where(m => m.Name.StartsWith("测试")).FindAll();
table.Where(m => m.Name.EndsWith("测试")).FindAll();

// 正则 
table.Where(m => m.Name.Regex("^测试")).FindAll();

// 支持MYSQL的MD5函数
table.Where(m => m.Name.MD5Equals('MD5字符串')).Find();

::: tip 以上例子只为方便演示,如果放在一起运行可能查询结果会不同预期,原因是连续使用 Where 会叠加查询条件! ::: ::: tip 正则表达式 正则表达式是一种用于匹配和操作文本的强大工具,它是由一系列字符和特殊字符组成的模式,用于描述要匹配的文本模式。

正则表达式可以在文本中查找、替换、提取和验证特定的模式。

详细查阅 点击链接 :::

或逻辑查询

实现或逻辑查询除了单个 Lambda 表达式中 使用 OR 组合,也可以使用 Lambda 集合来实现,因为在 ORMXLambda 数组做 Where 参数时以 OR 拼接的。

entity.Table<Model.User>().Where(
    m => m.Name.Equals("知时"), 
    m => m.Name.Equals("测试")
).FindAll();

或者

List<Expression<Func<Model.User, bool>>> expressions = new List<Expression<Func<User, bool>>>();
expressions.Add(m => m.Name.Equals("知时"));
expressions.Add(m => m.Name.Equals("测试"));
entity.Table<Model.User>().Where(expressions.ToArray()).FindAll();

多表连接

请见数据连接 JOIN 示例 ::: tip Where 最多支持五张表连接查询 :::

动态字段

如果遇到编码阶段还未知具体是哪个字段的情况,可以使用动态字段解决

string[] fields = new string[] { "CompanyName", "LoginName" };
foreach(var field in fields) 
{
    table.Where(m => m.FieldName(field).Equals("测试"));
}
table.FindAll();

连续查询 WhereReset

是有时候我们需要连续查询获取需要的数据,这时候就要用到 WhereReset

// Where In
table.Where(m => m.Sex.InList(1,2)).FindAll();
table.WhereReset(m => m.Sex.NotInList(1,2)).FindAll();

分组 Group

通常分组结合计算函数一起使用,关于 SQL 分组介绍可以 查阅链接

// 以下例子会按照性别分组查询不同性别的登录次数
table
.GroupBy(m => new[] { m.Sex })
.Count(m => m.LoginCount, "CountLoginCount")
.FindAll();

Having 用于在分组之后对分组的结果进行筛选。

table
.GroupBy(m => new[] { m.Sex })
.Count(m => m.LoginCount, "CountLoginCount")
.Having(e => e.Mobile == "12345678910")
.FindAll();

数据排序 ASC / DESC

以下例子会根据数据的创建时间从远到近,筛选出前10条进行删除

table.Where(m => m.Sex == 1).Limit(10).OrderBy(m => m.CreateTime, ASC).Delete();

限制数量 LIMIT

table.Where(m => m.Sex == 1).Limit(10).Delete();

::: tip Limit 因为只搭配 Delete、Update 方法使用所以只又有一个参数长度 :::

数据连接 JOIN

using (var table = entity.Table<Model.User>())
{
    table.Join<Model.People>((e, m) => e.Id == m.UserId)
        .Where<Model.User, Model.People>((m,p) => m.Id == "1" && p.Id == "2")
        .FindAll();
}

SQL 事务 Transaction

using (var tr = entity.Transaction())
{
    tr.Begin();

    var table = tr.Table<Model.User>()
        .Column(m => new[] { m.Id })
        .Distinct(m => new[] { m.Id, m.Name })
        .Where(m => m.Id == "123123")
        .Asc(m => m.Id)
        .Find();

    tr.Commit();
}

::: tip 请不用担心例子中 table 的销毁问题,因为 tr 销毁时会带着所有创建的 table 一起销毁 :::

节点保存与回退

using (var tr = entity.Transaction())
{
    tr.Begin();
    tr.Save("testPoint1");

    // 这里有数据操作...

    tr.Save("testPoint2");

    // 这里又有数据操作...

    tr.Rollback("testPoint2");

    // 回退后第二次数据操作失效
    tr.Commit();
}