【手撸一个ORM】第一步、实体约定和描述
一、约定
数据实体必须实现 IEntity 接口,该接口定义了一个int类型的Id属性,既每个实体必须有一个名称为Id的自增主键。
若数据表的主键列名称不是Id,可以通过 [MyKey("主键列名")] 对该属性进行描述
namespace MyOrm.Commons
{
public interface IEntity
{
int Id { get; set; }
}
}
二、实体描述
MyTableAttribute,用于约定实体和数据表的关联关系,若实体名称和数据表名一直,可省略此描述
MyKeyAttribute,用于约定实体的主键,若数据表主键名称不是Id,可通过此描述约定Id属性映射的数据表的主键名
MyColumnAttribute,InsertIgnore=true 插入时忽略此属性;UpdateIgnore=true 更新时忽略此属性;Ignore=true 插入和更新时忽略该属性;ColumnName 若属性名和列名不一致,使用此属性约定映射的数据表列名
MyForeignKeyAttribute,ForeignKey 用于约定导航属性和外键列,若外键名不为 “导航属性名 + Id”,则需要通过此描述进行约定。
using System; namespace MyOrm.Attributes
{
[AttributeUsage(AttributeTargets.Class)]
public class MyTableAttribute : Attribute
{
public string TableName { get; } public MyTableAttribute(string tableName)
{
TableName = tableName;
}
} [AttributeUsage(AttributeTargets.Property)]
public class MyKeyAttribute : Attribute
{
public bool IsIncrement { get; set; } = true; public string FieldName { get; set; }
} [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class MyColumnAttribute : Attribute
{
public string ColumnName { get; set; } public bool Ignore { get; set; } public bool InsertIgnore { get; set; } public bool UpdateIgnore { get; set; }
} [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class MyForeignKeyAttribute : Attribute
{
public string ForeignKey { get; set; } public string MasterKey { get; set; } = "Id"; public MyForeignKeyAttribute(string foreignKey)
{
ForeignKey = foreignKey;
}
}
}
三、示例:
using MyOrm.Attributes;
using MyOrm.Commons;
using System; namespace ConsoleApp1
{
// 实体对应的数据表名为 Base_Student
[MyTable("Base_Student")]
public class Student : IEntity
{
// 数据表的主键名称为StudentId
[MyKey(FieldName = "StudentId")]
public int Id { get; set; } public string StudentName { get; set; } public string Mobile { get; set; } public string Card { get; set; } public string State { get; set; } public DateTime? Birthday { get; set; } // 更新时忽略学校Id
[MyColumn(UpdateIgnore = true)]
public int FKSchoolId { get; set; } // 是否删除字段只能通过 Delete 方法修改,Update时需忽略该属性
[MyColumn(UpdateIgnore = true)]
public bool IsDel { get; set; } // 创建时间和创建人只在创建时指定,其他时候不能修改
[MyColumn(UpdateIgnore = true)]
public DateTime CreateAt { get; set; } [MyColumn(UpdateIgnore = true)]
public string CreateBy { get; set; } public DateTime UpdateAt { get; set; } public string UpdateBy { get; set; } // 导航属性的外键为 FKSchoolId,若不指定,默认为SchoolId
[MyForeignKey("FKSchoolId")]
public School School { get; set; }
}
}
【手撸一个ORM】第一步、实体约定和描述的更多相关文章
- 【手撸一个ORM】MyOrm的使用说明
[手撸一个ORM]第一步.约定和实体描述 [手撸一个ORM]第二步.封装实体描述和实体属性描述 [手撸一个ORM]第三步.SQL语句构造器和SqlParameter封装 [手撸一个ORM]第四步.Ex ...
- 【手撸一个ORM】第十步、数据操作工具类 MyDb
说明 其实就是数据库操作的一些封装,很久不用SqlCommand操作数据库了,看了点园子里的文章就直接上手写了,功能上没问题,但写法上是否完美高效无法保证,建议有需要的朋友自己重写,当然如果能把最佳实 ...
- 【手撸一个ORM】第六步、对象表达式解析和Select表达式解析
说明 一个Orm自然不仅仅包含条件表达式,还会有如下的场景: OrderBy(s => s.StudentName) Select<StudentDto>(s => new S ...
- 【手撸一个ORM】第七步、SqlDataReader转实体
说明 使用Expression(表达式目录树)转Entity的文章在园子里有很多,思路也大致也一样,我在前面有篇文章对解决思路有些说明,有兴趣的小伙伴可以看下 (传送门),刚接触表达式目录树时写的,不 ...
- 【手撸一个ORM】第五步、Expression(表达式目录树)转换为Where子句
说明 在SQL中,查询.修改比较常用到WHERE子句,在这里根据使用场景不同,定义了两个类,一个用于查询,一个用于修改(插入)操作.原因是: 查询操作支持一级导航属性查询,如student.Schoo ...
- 【手撸一个ORM】第四步、Expression(表达式目录树)扩展
到这里,Orm的基架已经搭起来了,接下来就是激动人心的部分,表达式目录树转Sql语句,SqlDataReader转数据实体等等,但是在这之前,我们需要扩展下表达式目录树的方法,以方便后面的相关操作. ...
- 【手撸一个ORM】第八步、查询工具类
一.实体查询 using MyOrm.Commons; using MyOrm.DbParameters; using MyOrm.Expressions; using MyOrm.Mappers; ...
- 【手撸一个ORM】第二步、封装实体描述和实体属性描述
一.实体属性描述 [MyProperty.cs] Name,属性名称 PropertyInfo,反射获取的属性信息,后面很多地方需要通过该属性获取对应的实体类型,或调用SetValue进行赋值 Fie ...
- 【手撸一个ORM】第三步、SQL语句构造器和SqlParameter封装
既然是数据库工具,自然少不了增删改查的sql语句,在这里将这些常用SQL拼接操作集成到 [SqlServerBuilder.cs] 当中,方便后面调用. 近几年在项目中一直使用Dapper操作数据库, ...
随机推荐
- 关于跨域获取cookie问题的解决
需求是有2个域名:www.a.com和www.b.com,b.com需要获取a.com中的cookie,解决方法是这样的: 在a.com编写一个设置cookie的页面:set_cookie.php 代 ...
- VC++中list::list的使用方法总结
本文主题 这几天在做图像处理方面的研究,其中有一部分是关于图像分割方面的,图像目标在分割出来之后要做进一步的处理,因此有必要将目标图像的信息保存在一个变量里面,一开始想到的是数组,但是马上就发现使用数 ...
- Android Studio 字体大小和背景色的设置
豆绿色的RGB值:#C7EDCC 1.打开Android Studio——>Ctrl+Alt+s 或者 File——>Settings 2.在弹窗中选中“Colors&Fonts” ...
- L95
The children squealed with delight when they saw the puppy.The signal will be converted into digital ...
- hdu-5806 NanoApe Loves Sequence Ⅱ(尺取法)
题目链接: NanoApe Loves Sequence Ⅱ Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/13107 ...
- TF-IFD算法及python实现关键字提取
TF-IDF算法: TF:词频(Term Frequency),即在分词后,某一个词在文档中出现的频率. IDF:逆文档频率(Inverse Document Frequency).在词频的基础上给每 ...
- bzoj 2850: 巧克力王国 K-D树
题目大意 http://www.lydsy.com/JudgeOnline/problem.php?id=2850 题解 对于每个人,我们发现它能够接受的巧克力中 如果对参数分别讨论,那么一定是一个连 ...
- 洛谷 P2919 [USACO08NOV]守护农场Guarding the Farm
题目描述 The farm has many hills upon which Farmer John would like to place guards to ensure the safety ...
- python json ajax django四星聚会
什么是json: JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器解析和生成.它基于JavaScript Programm ...
- python3 + selenium + eclipse 中报:Unable to find a matching set of capabilities
在环境python3 + selenium + eclipse 运行报错::Unable to find a matching set of capabilities 解决办法:Update Fire ...