(23)ASP.NET Core EF关系数据库建模
1.简介
一般而言,本部分中的配置适用于关系数据库。安装关系数据库提供程序时,此处显示的变为可用扩展方法(原因在于共享的Microsoft.EntityFrameworkCore.Relational包)。
2.表映射
表映射标识在数据库中哪张表应该进行内容查询和保存操作。
2.1约定
按照约定,每个实体将设置为映射到名称与DbSet<TEntity> 属性(公开派生上下文中的实体)相同的表中。如果给定DbSet<TEntity>实体中不包含,则使用类名称。
2.2数据注释
可以使用数据注释来配置类型映射表。
[Table("blogs")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
你还可以指定表所属的架构(数据库)。
[Table("blogs", Schema = "blogging")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
2.3Fluent API
你可以使用熟知的API来配置类型映射到的表。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable("blogs");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
你还可以指定表所属的架构(数据库)。
modelBuilder.Entity<Blog>().ToTable("blogs", schema: "blogging");
3.列映射
列映射标识在数据库中应从哪些列数据中进行查询和保存。
3.1约定
按照约定,每个属性将会设置为映射到与属性具有相同名称的列。
3.2数据注释
可以使用数据注释来配置属性映射到的那一列。
namespace EFModeling.DataAnnotations.Relational.Column
{
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
}
public class Blog
{
[Column("blog_id")]
public int BlogId { get; set; }
public string Url { get; set; }
}
}
3.3Fluent API
您可以使用熟知的API来配置属性映射到的列。
namespace EFModeling.FluentAPI.Relational.Column
{
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.BlogId)
.HasColumnName("blog_id");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
}
4.数据类型
数据类型是指属性所映射到的列的数据库特定类型。
4.1约定
按照约定,数据库提供程序基于属性的.NET类型选择数据类型。它还会考虑其他元数据,如配置的最大长度、属性是否是主键的一部分等。例如,SQL Server的DateTime、nvarchar(max) 用作键的属性。
4.2数据注释
您可以使用数据注释为列指定精确的数据类型。例如,下面的代码将Url配置为一个非unicode字符串,其最大200长度。Rating为5至2小数位。
public class Blog
{
public int BlogId { get; set; }
[Column(TypeName = "varchar(200)")]
public string Url { get; set; }
[Column(TypeName = "decimal(5, 2)")]
public decimal Rating { get; set; }
}
4.3Fluent API
你还可以使用熟知的API为列指定相同的数据类型。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>(eb =>
{
eb.Property(b => b.Url).HasColumnType("varchar(200)");
eb.Property(b => b.Rating).HasColumnType("decimal(5, 2)");
});
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public decimal Rating { get; set; }
}
5.主键
为每个实体类型的键引入primary key(主键)约束。
5.1约定
按照约定,会将数据库中的主键命名为PK_<type name>。
5.2数据注释
不能使用数据批注配置主键的关系数据库的特定方面。
5.3Fluent API
你可以使用API在数据库中配置primary key(主键)约束的名称。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasKey(b => b.BlogId)
.HasName("PrimaryKey_BlogId");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
6.默认架构
如果没有为该对象显式配置架构,则默认架构为将在其中创建对象的数据库架构。
6.1约定
按照约定,数据库提供程序将选择最适合的默认架构。例如,Microsoft SQL Server将使用dbo架构,而且sqlite将不使用架构(因为sqlite不支持架构)。
6.2数据注释
不能使用数据批注设置默认架构。
6.3Fluent API
可以使用API来指定默认架构。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("blogging");
}
}
7.默认值
如果插入新行,但没有为该列指定值,则列的默认值为要插入的值。
7.1约定
按照约定,未配置默认值。
7.2数据注释
不能使用数据批注设置默认值。
7.3Fluent API
你可以使用API指定属性的默认值。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Rating)
.HasDefaultValue();
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public int Rating { get; set; }
}
还可以指定用于计算默认值的SQL片段。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Created)
.HasDefaultValueSql("getdate()");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
public DateTime Created { get; set; }
}
8.索引(关系数据库)
关系数据库中的索引映射到与实体框架核心中的索引相同的概念。
8.1约定
按照约定,索引命名为IX_<type name>_<property name>。对于复合索引<property name>,将成为以下划线分隔的属性名称列表。
8.2数据注释
不能使用数据批注配置索引。
8.3Fluent API
你可以使用熟知的API来配置索引的名称。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.HasName("Index_Url");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
你还可以指定筛选器。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.HasFilter("[Url] IS NOT NULL");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
使用SQL Server提供程序EF为唯一索引中包含的所有可以为null的列添加"IS NOT NULL"筛选器。若要重写此约定,可以null提供一个值。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.IsUnique()
.HasFilter(null);
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
在SQL Server索引中包含列,当查询中的所有列都作为键列或非键列包含在索引中时,可以通过包含列配置索引以显著提高查询性能。
class MyContext : DbContext
{
public DbSet<Post> Posts { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>()
.HasIndex(p => p.Url)
.IncludeProperties(p => new
{
p.Title,
p.PublishedOn
})
.HasName("Index_Url_Include_Title_PublishedOn");
}
}
public class Post
{
public int PostId { get; set; }
public string Url { get; set; }
public string Title { get; set; }
public DateTime PublishedOn { get; set; }
}
参考文献:
表映射
列映射
数据类型
主键
默认架构
默认值
索引(关系数据库)
(23)ASP.NET Core EF关系数据库建模的更多相关文章
- asp.net core+ef core
asp.net core+ef core 官方的文档https://docs.asp.net/en/latest/tutorials/first-mvc-app/start-mvc.html 先来看一 ...
- C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现之方法二:加入缓存机制
在上一篇文章中我用递归方法实现了管理菜单,在上一节我也提到要考虑用缓存,也算是学习一下.Net Core的缓存机制. 关于.Net Core的缓存,官方有三种实现: 1.In Memory Cachi ...
- Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本)
Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本) 原创 2016年07月22日 10:33:51 23125 6月随着.NET COR ...
- C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现
今天做一个管理后台菜单,想着要用无限极分类,记得园子里还是什么地方见过这种写法,可今天找了半天也没找到,没办法静下心来自己写了: 首先创建节点类(我给它取名:AdminUserTree): /// & ...
- ASP.NET Core&EF 笔记
首先创建Asp.net Core项目,然后通过 NuGet 安装 EntityFrameworkCore: Microsoft.EntityFrameworkCore.SqlServer Micros ...
- (17)ASP.NET Core EF基于数据模型创建数据库
1.简介 使用Entity Framework Core构建执行基本数据访问的ASP.NET Core MVC应用程序.使用迁移(Migrations)基于数据模型创建数据库,你可以在Windows上 ...
- ASp.net Core EF ActionFilterAttribute AOP
在项目中经常遇到一些数据的修改,很多时候业务方需要一个修改日志记录,这里我们计划用mssql数据库来存放日志记录,用EF来操作,记录日志可以用mvc的ActionFilterAttribute 来完成 ...
- 基于Asp.net core + EF + Sqlite 5分钟快速上手一个小项目
虽然该方法不会用在实际开发中,但该过程对于初学者还是非常友好的,真应了麻雀虽小,五脏俱全这句话了.好了不多废话了,直接开始!! 1.建立一个名为test的Asp.net core web应用程序 这一 ...
- asp.net Core EF core ( Entity Framework 7 ) 数据库更新维护
CreateDatabaseIfNotExists等之前的API已经废弃,现在采用的是微软封装好,简化.高效的API,migrations 因为,旧API,要付出高昂的代价,以及局限性 打开VS20 ...
随机推荐
- js数组的增删改查
array 数组的增删改: push 从数组后面推入一个元素或多个元素 var arr = [1,2,3]; // 返回:修改后数组的长度 arr.push(4,5,6); pop 删除数组最后一 ...
- mysql 5.7 Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column ...报错
使用mysql在执行一条插入语句时 , ', "hhh"); 报错:Expression #1 of ORDER BY clause is not in GROUP BY clau ...
- SUSE Linux Enterprise 15 SP1 系统安装
从 SUSE Linux Enterprise Server 15 开始,安装媒体仅包含安装程序 - 一个用于安装.更新和注册 SUSE Linux Enterprise Server 的基于命令行的 ...
- ElasticSearch实战系列三: ElasticSearch的JAVA API使用教程
前言 在上一篇中介绍了ElasticSearch实战系列二: ElasticSearch的DSL语句使用教程---图文详解,本篇文章就来讲解下 ElasticSearch 6.x官方Java API的 ...
- postgres 数据库 citus 集群分片
前言 什么时候需要考虑做数据切分? 1.能不切分尽量不要切分 并不是所有表都需要进行切分,主要还是看数据的增长速度.切分后会在某种程度上提升业务的复杂度,数据库除了承载数据的存储和查询外,协助业务更好 ...
- Inkscape 旋转并复制
画一个图形,点击图标. 然后图标中心有个十字叉, 然后把这个十字叉拖到你想要旋转的地方. 然后shift+ctrl+m打开变换菜单. 选择旋转选项卡,然后设置角度,点击应用.就可以旋转了,如果配合ct ...
- 《完美解决系列》Android5.0以上 Implicit intents with startService are not safe
在Android6.0上,使用了以下代码: Intent intent = new Intent(); intent.setAction("xxx.server"); bindSe ...
- Spring Boot (十二): Spring Boot 邮件服务
最早我们发邮件的时候是使用 JavaMail 来发送邮件,而在 Spring Boot 中, Spring Boot 帮我们将 JavaMail 封装好了,是可以直接拿来使用的. 1. 依赖文件 po ...
- 某CTF平台一道PHP代码注入
这道题以前做过但是没有好好的总结下来.今天又做了一下,于是特地记录于此. 首先就是针对源码进行审计: 关于create_function这个函数可以看一下这个:http://www.php.cn/ph ...
- System NT Kernel & System占用CPU 12%左右 终极解决方案,原来是更新惹的祸
任务管理器发现 system进程持续占用12%左右的cpu,网上搜索到的很多方法均无效 误打误撞发现了这个方法,亲测可用 卸载系统补丁(KB41000347),提升10%的cpu性能 卸载补丁前: ...