欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

微软跨平台ORM框架之EFCore — 约定与属性映射

程序员文章站 2024-01-21 12:08:52
EFCore中的约定简单来说就是规则,CodeFirst基于模型的约定来映射表结构。除此之外还有Fluent API、Data Annotations(数据注释) 可以帮助我们进一步配置模型。 按照这三者的优先级高低排序分别是:Fluent API、Data Annotations(数据注释)、约定 ......

efcore中的约定简单来说就是规则,codefirst基于模型的约定来映射表结构。除此之外还有fluent api、data annotations(数据注释) 可以帮助我们进一步配置模型。

按照这三者的优先级高低排序分别是:fluent api、data annotations(数据注释)、约定。

 

1.约定

public class person
    {
        public int id { get; set; }
        public int age { get; set; }
        public bool status { get; set; }
        public string name { get; set; }
        public datetime createtime { get; set; }
    }

1.1 主键约定

我们有这样的一个person类,在实体中如果有名为id的字段,或者实体名+id的字段如:personid,那么efcore生成的表会自动标识为主键。并且如果它的类型是int或guid则会默认自增长。

映射之后的表结构:

微软跨平台ORM框架之EFCore  — 约定与属性映射

 

我们可以看到c#中的int、bool、string、datetime,分别映射为 int,bit,navarchar(max),datetime2(7)。这是因为efcore的默认约定是这么规定的。道友们可能会想自定义的映射,比如把string映射会varcher,datetime映射为datetime。嗯。。这就需要借助fluent api或data annotations了。

1.2 外键约定

新建一个订单类,并添加person类型的字段,以及personid(以类名+id的形式),并在上下文中注册。efcore在映射表时会根据我们给定person类型和personid来添加外键约束。

  public class order
    {
        public guid id { get; set; }
        public int personid { get; set; }
        public person person { get; set; }
        public string address { get; set; }
        public string phone { get; set; }
    }

修改progarm.cs代码

class program
    {
        static void main(string[] args)
        {

            var context = new coredbcontext();
            // 删除数据库
            context.database.ensuredeleted();
            // 告诉efcore我们要创建数据库
            context.database.ensurecreated();
            // 初始化数据
            var person = new person()
            {
                name = "季某人",
                age = 11,
                status = true,
                createtime = datetime.now,
            };
            var person2 = new person()
            {
                name = "季某人",
                age = 11,
                status = true,
                createtime = datetime.now,
            };
            var order = new order()
            {
                personid = 1,
                address = "地球xx",
                phone = "00000"
            };
            context.person.add(person);
            context.person.add(person2);
            // 这里因为添加了外键,所以要先保存person,不然会报外键的错误
            context.savechanges();
            context.order.add(order);
            context.savechanges();

            //console.writeline("hello world!");
        }
    }

启动项目,然后查看数据库。

微软跨平台ORM框架之EFCore  — 约定与属性映射

 

 微软跨平台ORM框架之EFCore  — 约定与属性映射

可以看到数据完成了初始化,并且添加了外键约束。

 

2.data annotations(数据注释)

数据注释就是在属性上添加一些特性标签,告诉efcore我们要映射的类型是什么样的,当默认的映射不能满足我们的需求时,就可以使用数据注释了。例如前面的映射,string类型映射为数据库的nvarchar(max),datetime映射为datetime2(7)。 使用数据注释可以改变为我们想要映射成的类型,例如:string映射成varvhar。

添加一个新类orderdetail,并添加数据注释。

 public class orderdetail
    {
        [key] // 标识主键
        public int id { get; set; }
        [column(typename = "varchar(50)")] // 列的数据类型
        [required] // 必填列
        public string price { get; set; }
        public datetime? createtime { get; set; }
        [column("ordercode")] // 列的显示名字
        [stringlength(50)] // 列的长度
        public string code { get; set; }
        public guid? orderid { get; set; }

        public order order { get; set; }

    }

启动项目,观察映射成的表结构。与实体中的配置一样。

微软跨平台ORM框架之EFCore  — 约定与属性映射

基本常用的就这些,其他的用到的时候可以去官网文档上找。

3.fluent api

fluent api 相较于 数据注释更加灵活。它的配置需要写在自定义的上下文类中的onmodelcreating方法中。

比如改变表名,数据类型之类的

 

微软跨平台ORM框架之EFCore  — 约定与属性映射

效果和数据注释是一样的,值得注意的是当fluent api 和数据注释同时配置一个属性时,fluent api会覆盖掉数据注释。

除了上述之外还可以利用fluent api 统一表的命名规范:例如 "t_+实体名".

  protected override void onmodelcreating(modelbuilder modelbuilder)
        {
            foreach (var item in modelbuilder.model.getentitytypes())
            {
                modelbuilder.entity(item.name).totable("t_" + item.clrtype.name);
            }
        }

遍历要映射的实体然后加上 "t_" 前缀。

微软跨平台ORM框架之EFCore  — 约定与属性映射

 

具体差异可以观看微软efcore文档,传送门:https://docs.microsoft.com/zh-cn/ef/core/modeling/relational/data-types