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 集合来实现,因为在 ORMX 中 Lambda 数组做 Where 参数时以 OR 拼接的。
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();
}