前言

简单介绍一下EfCore 的模型篇

正文

内容来源:

配置模型

配置模型的方式,一种是fluent api 还一种是属性的方式。

public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}

那么fluent api 怎么配置呢?

public class BloggingContext : DbContext
{
public DbSet<Blog> Blogs { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.IsRequired();
}
}

可以这么配置。

但是实际上项目中一般不会这么干。

理由也很简单,因为OnModelCreating 如果表很多的话,那么会非常臃肿,这样就不好维护了。

一般都是单独写一个配置:

public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
{
public void Configure(EntityTypeBuilder<Blog> builder)
{
builder.Property(b => b.Url)
.IsRequired();
}
}

然后:

这样每次加一个然后就要在OnModelCreating 增加配置就好。

然后官方还提供了一种方法:

modelBuilder.ApplyConfigurationsFromAssembly(typeof(BlogEntityTypeConfiguration).Assembly);

这种就是读取全部该程序集下面的实现IEntityTypeConfiguration的类,然后调用Configure。

然后官方也提示了。

应用配置的顺序是不确定的,因此仅当顺序不重要时才应使用此方法。

然后另外一种就是数据注释来配置模型:

这种数据注释的方式,没有fluent api的优先级高。

也就是说数据注释的,会被fluent api 覆盖。

这种和我们以前的方式一样哈。

那么这两种方式该如何选择呢?

其实这两种方式可以结合使用,然后fluent api 功能更强大,有些无法用数据注释来实现的,可以用fluent api。

如何包含到Ef Core 模型中呢?

有3中方式可以加入到EF Core 模型中。

第一种是:

public DbSet Blogs { get; set; }

第二种是作为导航属性默认加进去的:

前两种都是约定,第三种是调用方法:

在onModelCreating 中加入。

还有一种是希望模型中不包含某一种类型。

[NotMapped]
public class BlogMetadata
{
public DateTime LoadedFromDatabase { get; set; }
}

然后api 的方式这样用:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Ignore<BlogMetadata>();
}

一般什么时候会用到呢? 一般是约定就包含了,但是自己又不希望包含。

比如前面导航属性,可能建立模型的就不将其加入实体中。

然后又一个从迁移中排除,倒是很好用的。

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUser>()
.ToTable("AspNetUsers", t => t.ExcludeFromMigrations());
}

这个有什么用呢?

那就是相同的实体类型映射到多个DbContext 类型中使用。

这样会有一个问题,如果一个实体改变了,那么多个DbContext 的迁移都会为此作出动作。

那么这个时候就要保证只有一个DbContext 进行迁移。 理由也很简单,如果一个Dbcontext 进行了迁移,其他的Dbcontext 迁移就会报错了,因为这个时候数据库的表发生了变化。

然后表名称:

按照约定,每个实体类型都将设置为映射到与公开实体的 DbSet 属性名称相同的数据库表。 如果给定实体不存在 DbSet,则使用类名称。

这个约定就必须记住了,很重要,有些人可能还不知道DbSet 属性名称有这个约定。

[Table("blogs")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}

然后fluent api:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable("blogs");
}

然后下面这个是表的架构:

[Table("blogs", Schema = "blogging")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}

fluent api 是下面这个:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable("blogs", schema: "blogging");
}

使用关系数据库时,表按约定在数据库的默认架构中创建。 例如,Microsoft SQL Server 将使用 dbo 架构(SQLite 不支持架构)。

那么什么是表架构呢?

这个要从一段历史开始。

在sql server 2000的时候,访问数据库通过,数据库名.用户名.表名来访问。

而sql server 2005的时候,访问数据库是通过,数据库名.架构名.表名来访问的。

为什么做出这个改变呢? 那就是通过用户名来访问,不好管理权限。

后面引入架构名来对表进行逻辑分组,从而达到控制权限的目的。

比如一个数据库有多个架构,那么用户可以分配到对哪几个架构有什么权限,更加细节了。

而为什么我们一般访问的时候有一个dbo呢? 是因为我们默认使用的就是dbo。

那么为什么叫做dbo呢? 这个名字随便来的吗? 其实不是。

是这样的,在2000创建表的时候数据库名.用户名.表名来访问,这个时候默认用户名就是dbo。

这个时候2005的时候为了兼容这个东西,那么就使用了dbo作为默认架构了,大体就是这么回事。

表注释:

[Comment("Blogs managed on the website")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
} protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasComment("Blogs managed on the website");
}

前面说过fluent api 比我们的数据注释要更加强大,下面看几个数据注释无法搞定的。

比如视图映射:

modelBuilder.Entity<Blog>()
.ToView("blogsView", schema: "blogging");

表值函数映射:

https://docs.microsoft.com/zh-cn/ef/core/modeling/entity-types?tabs=data-annotations#table-valued-function-mapping

然后fluent api 还至此共享类型实体类型,这个用的比较少。

https://docs.microsoft.com/zh-cn/ef/core/modeling/entity-types?tabs=fluent-api#shared-type-entity-types

下一节介绍乐观并发锁。

c# 框架系列 ———— EFCore 模型篇 [一]的更多相关文章

  1. Google C++测试框架系列入门篇:第三章 基本概念

    上一篇:Google C++测试框架系列入门篇:第二章 开始一个新项目 原始链接:Basic Concepts 词汇表 版本号:v_0.1 基本概念 使用GTest你肯定会接触到断言这个概念.断言是用 ...

  2. Google C++测试框架系列入门篇:第二章 开始一个新项目

    上一篇:Google C++测试框架系列入门篇:第一章 介绍:为什么使用GTest? 原始链接:Setting up a New Test Project 词汇表 版本号:v_0.1 开始一个新项目 ...

  3. SpringMVC 框架系列之组件概述与配置详解

    在上一篇文章 SpringMVC 框架系列之初识与入门实例 的实例中,我们已经知道,SpringMVC 框架是一个 web 层的框架,本篇文章就详细解释一下 SpringMVC 框架具体文件的配置以及 ...

  4. Farseer.net轻量级ORM开源框架 V1.x 入门篇:新版本说明

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:没有了 下一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置 前言 V1.x版本终于到来了.本次 ...

  5. Mysql高手系列 - 第9篇:详解分组查询,mysql分组有大坑!

    这是Mysql系列第9篇. 环境:mysql5.7.25,cmd命令中进行演示. 本篇内容 分组查询语法 聚合函数 单字段分组 多字段分组 分组前筛选数据 分组后筛选数据 where和having的区 ...

  6. java高并发系列 - 第26篇:学会使用JUC中常见的集合,常看看!

    这是java高并发系列第26篇文章. 环境:jdk1.8. 本文内容 了解JUC常见集合,学会使用 ConcurrentHashMap ConcurrentSkipListMap Concurrent ...

  7. Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)

    在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...

  8. Spring框架系列(5) - 深入浅出SpringMVC请求流程和案例

    前文我们介绍了Spring框架和Spring框架中最为重要的两个技术点(IOC和AOP),那我们如何更好的构建上层的应用呢(比如web 应用),这便是SpringMVC:Spring MVC是Spri ...

  9. Spring框架系列(14) - SpringMVC实现原理之DispatcherServlet处理请求的过程

    前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet ...

  10. 【Windows编程】系列第三篇:文本字符输出

    上一篇我们展示了如何使用Windows SDK创建基本控件,本篇来讨论如何输出文本字符. 在使用Win32编程时,我们常常要输出文本到窗口上,Windows所有的文本字符或者图形输出都是通过图形设备接 ...

随机推荐

  1. SQLServer 导入 Excel 表数据报错“文本被截断。。。”

    报错详情(关键信息就是:文本被截断) 错误 0xc020901c: 数据流任务 1: 输出"Excel 源输出"(9) 上的 输出列"xxxxx"(78) 出错 ...

  2. PostgreSql一个月学习计划

    1.背景 国内使用数据库最多的莫过于mysql,大部分程序员第一次接触数据库就是mysql.(毕竟免费的 = =!)但近年来,有一些黑马出现(如下图),其中表现最突出的莫过于PostgreSQL.特规 ...

  3. aardio ide 字体 及设置

    需求 aardio ide 只支持一个字体,英文字体肯定是Fira 但是中文字体不好,所以只好将两个字体合并上使用. 有教程.但是我发现已经有合并好的,就拿来使用吧放到fonts目录里面 代码 imp ...

  4. audio currentTime 设置后,重置成0,解决方案(流文件-下载文件)

    audio currentTime 设置后,重置成0,解决方案 第一步-流文件-下载文件: 先查看你的mp3文件是 流文件,还是下载文件. 检测方式,就是放到浏览器回车.在线播放就是流文件,直接下载了 ...

  5. 基于python的环境噪声监测报警系统实例解析

    一 系统简介 1.简介 该系统可以实时显示噪声量大小,并进行一段时间的噪声统计. 2.特性 实现噪声值的统计 实现了噪声显示 完整的主题和样式控制 多线程的运行模式 二 源码解析 1.串口db值获取: ...

  6. gRPC入门学习之旅(二)

    gRPC入门学习之旅(一) gRPC是一个高性能.通用的开源远程过程调用(RPC)框架,基于底层HTTP/2协议标准和协议层Protobuf序列化协议开发,支持众多的开发语言,由Google开源. g ...

  7. 关于C++ 多态实现技术的深度解析(vfptr,vftable)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  8. drf(过滤、排序、异常)

    一. 过滤组件 1 内置过滤组件SearchFilter # 缺点: 外键字段的搜索操作将会抛出异常: Related Field got invalid lookup: icontains # 1) ...

  9. linux下永久添加静态路由-不同

    linux下永久添加静态路由-不同 添加路由的命令: 1,route add route add -net 192.56.76.0 netmask 255.255.255.0 dev eth0#添加一 ...

  10. LOTO示波器_从零开始手把手测电源开环增益/电源环路频响曲线/PSM

    我们之前有篇文章从理论到实践演示了如何测量电源环路的开环增益曲线,不过偏重于理论和原理,没有很多细节的展现,所以这片文章从另外的角度,从零基础开始,手把手一步一步演示如果进行实操测试. 之前的那篇文章 ...