一、约定

数据实体必须实现 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】第一步、实体约定和描述的更多相关文章

  1. 【手撸一个ORM】MyOrm的使用说明

    [手撸一个ORM]第一步.约定和实体描述 [手撸一个ORM]第二步.封装实体描述和实体属性描述 [手撸一个ORM]第三步.SQL语句构造器和SqlParameter封装 [手撸一个ORM]第四步.Ex ...

  2. 【手撸一个ORM】第十步、数据操作工具类 MyDb

    说明 其实就是数据库操作的一些封装,很久不用SqlCommand操作数据库了,看了点园子里的文章就直接上手写了,功能上没问题,但写法上是否完美高效无法保证,建议有需要的朋友自己重写,当然如果能把最佳实 ...

  3. 【手撸一个ORM】第六步、对象表达式解析和Select表达式解析

    说明 一个Orm自然不仅仅包含条件表达式,还会有如下的场景: OrderBy(s => s.StudentName) Select<StudentDto>(s => new S ...

  4. 【手撸一个ORM】第七步、SqlDataReader转实体

    说明 使用Expression(表达式目录树)转Entity的文章在园子里有很多,思路也大致也一样,我在前面有篇文章对解决思路有些说明,有兴趣的小伙伴可以看下 (传送门),刚接触表达式目录树时写的,不 ...

  5. 【手撸一个ORM】第五步、Expression(表达式目录树)转换为Where子句

    说明 在SQL中,查询.修改比较常用到WHERE子句,在这里根据使用场景不同,定义了两个类,一个用于查询,一个用于修改(插入)操作.原因是: 查询操作支持一级导航属性查询,如student.Schoo ...

  6. 【手撸一个ORM】第四步、Expression(表达式目录树)扩展

    到这里,Orm的基架已经搭起来了,接下来就是激动人心的部分,表达式目录树转Sql语句,SqlDataReader转数据实体等等,但是在这之前,我们需要扩展下表达式目录树的方法,以方便后面的相关操作. ...

  7. 【手撸一个ORM】第八步、查询工具类

    一.实体查询 using MyOrm.Commons; using MyOrm.DbParameters; using MyOrm.Expressions; using MyOrm.Mappers; ...

  8. 【手撸一个ORM】第二步、封装实体描述和实体属性描述

    一.实体属性描述 [MyProperty.cs] Name,属性名称 PropertyInfo,反射获取的属性信息,后面很多地方需要通过该属性获取对应的实体类型,或调用SetValue进行赋值 Fie ...

  9. 【手撸一个ORM】第三步、SQL语句构造器和SqlParameter封装

    既然是数据库工具,自然少不了增删改查的sql语句,在这里将这些常用SQL拼接操作集成到 [SqlServerBuilder.cs] 当中,方便后面调用. 近几年在项目中一直使用Dapper操作数据库, ...

随机推荐

  1. enable nested VT in VM

    问题描述: 处理器支持VT-x,并且已经在BIOS中开启了VT-x.在host os上用VMware Workstation安装了一个Ubuntu虚拟机,在虚拟机中执行“cat /proc/cpuin ...

  2. OpenCV——PS滤镜 漩涡 vertex

    // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...

  3. ACM学习历程—HDU 1272 小希的迷宫(并查集)

    Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就 ...

  4. finetune

    微调的具体方法和技巧有很多种,这里总结了在不同场景下的微调技巧: 1)新数据集比较小且和原数据集相似.因为新数据集比较小(比如<5000),如果fine-tune可能会过拟合:又因为新旧数据集类 ...

  5. ContextMenu的自定义

    1.针对整个ContextMenu, 自定义一个Style,去掉竖分割线       <Style x:Key="DataGridColumnsHeaderContextMenuSty ...

  6. nagios客户端安装与配置windows篇

    一.被监控的windows xp客户端的配置 1.安装NSClient++并安装下载地址: http://sourceforge.net/projects/nscplusNSClient++-0.3. ...

  7. Linux 包管理基础:apt、yum、dnf 和 dpkg

    https://linux.cn/article-8782-1.html 1. apt-get 安装( 在线) 会帮我把所有的依赖包都一起安装 apt-get install xxx 安装xxx .如 ...

  8. 转载:数据库应用开发工具Toad使用笔记

    由于网上TOAD中文教程很少,在网上摘抄了此文章便于学习,感谢原创者. TOAD使用笔记 1.把鼠标停在sql所在行,然后ctrl+Enter直接执行当前sql. 2.解决Toad对中文显示乱码问题( ...

  9. css水平居中方式

    1. text-align:center 这种方式只适合于内联元素或者文字处于块元素当中是,给块元素设置这个,那么块元素当中的文字或者内联元素则居中.兼容各种浏览器 <div class=&qu ...

  10. Redux API之creatStore

    createStore(reducer, [initialState]) 创建一个 Redux store 来以存放应用中所有的 state.应用中应有且仅有一个 store. 参数 reducer  ...