asp.net core系列 27 EF模型配置(索引,备用键,继承)
一.索引
索引是许多数据存储中的常见概念。虽然它们在数据存储中的实现可能会有所不同,但它们可用于更有效地基于列(或列集)进行查找。按照约定,用作外键每个属性 (或组的属性) 会自动创建索引。无法使用数据注释创建索引。
1.1 非唯一索引
Fluent API 在单个属性上指定索引。默认情况下,索引是非唯一的。如下代码示例在Blogs表上创建Url列索引:
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url);
}
}
1.2 唯一索引
下面代码指定索引是唯一的,这是在索引上加了(Unique)唯一约束。
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.IsUnique();
1.3 复合索引
class MyContext : DbContext
{
public DbSet<People> People { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.HasIndex(p => new { p.FirstName, p.LastName });
}
} public class People
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address{get;set;}
}
下面使用EF基于数据模型(People)创建数据表。在Migration中生成了索引的代码, 以及查看数据库People表的索引(官方文档中暂没有看到提供索引包含列设置)如下所示:
name: "IX_People_FirstName_LastName",
table: "People",
columns: new[] { "FirstName", "LastName" });

二.备用键
除主键之外,备用键用作每个实体实例的备用唯一标识符(跟主键一样具有唯一约束)。备用键可以用作关系的目标。当使用关系数据库时,这映射到备用键列上的唯一索引/约束的概念以及引用列的一个或多个外键约束。系统通常会在需要时为你引入备用键,你无需手动配置它们。不能使用数据注释配置备用键。
2.1 约定
按照约定,系统将在识别属性(不是主键)时为你引入备用键,充当关系的目标。如下面代码所示:
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>()
.HasOne(p => p.Blog)
.WithMany(b => b.Posts)
//Post中创建BlogUrl外建字段
.HasForeignKey(p => p.BlogUrl)
//Blog中设置唯一约束备份键
.HasPrincipalKey(b => b.Url);
}
} public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; } public List<Post> Posts { get; set; }
} public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; } public string BlogUrl { get; set; }
public Blog Blog { get; set; }
}
上面主体实体Blog中Url属性作为备用键,创建了AK_Blogs_Url唯一非聚集索引。在依赖实体Post中创建了BlogUrl外键字段, 使用EF基于数据模型(Blog和Post实体)创建数据库,如下图所示。

2.2 Fluent API
可以使用Fluent API将单个属性配置为备用键。
class MyContext : DbContext
{
public DbSet<Car> Cars { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
//配置备用键(唯一非聚集索引)
.HasAlternateKey(c => c.LicensePlate); // 创建复合备用键
// modelBuilder.Entity<Car>()
// .HasAlternateKey(c => new { c.State, c.LicensePlate });
}
} class Car
{
public int CarId { get; set; }
public string LicensePlate { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public string State { get; set; }
}
三.继承
EF 模型中的继承用于控制如何在数据库中表示实体类中的继承, 按照约定,由数据库提供程序决定如何在数据库中表示继承。有关如何使用关系数据库提供程序处理它,请查看”继承关系数据库“。如果模型中明确包含两个或多个继承类型,EF将仅设置继承。EF 不会扫描的基类或派生类型,可以在模型中包含类型,通过公开DbSet 继承层次结构中每个类型。不能使用数据注释来配置继承。
3.1 约定
下面示例中,有二个实体,通过公开Dbset类型,默认约定继承,如下所示:
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
public DbSet<RssBlog> RssBlogs { get; set; }
} public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
} public class RssBlog : Blog
{
public string RssUrl { get; set; }
}
使用EF基于数据模型(Blog和RssBlog实体)创建数据库。生成后,两个实体合并到一个Blogs表中,如下所示:


3.2 Fluent API
如果您不想公开DbSet对于层次结构中的一个或多个实体,您可以使用Fluent API确保它们包含在模型中。如果您不依赖约定,则可以使用明确指定基类型HasBaseType。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<RssBlog>().HasBaseType<Blog>();
}
}
3.3 discriminator隐藏属性
上面3.1示例中,创建了discriminator辨别者隐藏属性,是基于base entity的层级。因为它是模型中的一个属性,所以可以像配置其他属性一样配置它。例如,要设置默认情况下的最大长度。
modelBuilder.Entity<Blog>()
.Property("Discriminator")
.HasMaxLength(200);
discriminator鉴别器也可以映射到实体中的实际CLR属性
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasDiscriminator<string>("BlogType");
}
} public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
//discriminator
public string BlogType { get; set; }
} public class RssBlog : Blog
{
public string RssUrl { get; set; }
}
参考文献:
官方文档:EF索引
asp.net core系列 27 EF模型配置(索引,备用键,继承)的更多相关文章
- asp.net core系列 28 EF模型配置(字段,构造函数,拥有实体类型)
一. 支持字段 EF允许读取或写入字段而不是一个属性.在使用实体类时,用面向对象的封装来限制或增强应用程序代码对数据访问的语义时,这可能很有用.无法使用数据注释配置.除了约定,还可以使用Fluent ...
- asp.net core系列 29 EF模型配置(查询类型,关系数据库建模)
一.查询类型 此功能是EF Core 2.1中的新功能. EF Core除了实体类型之外,EF Core模型还可以包含查询类型,这些查询类型是针对“未映射到实体类型”的数据获取.比如视图,或只读数据表 ...
- asp.net core系列 23 EF模型配置(概述, 类型和属性的包含与排除)
一.模型配置概述 EF使用一组约定基于实体类的定义来构建模型. 可指定其他配置以补充或替代约定的内容.本系列介绍的配置可应用于面向任何数据存储的模型,以及面向任意关系数据库时可应用的配置. 数据库提供 ...
- asp.net core系列 26 EF模型配置(实体关系)
一.概述 EF实体关系定义了两个实体互相关联起来(主体实体和依赖实体的关系,对应数据库中主表和子表关系). 在关系型数据库中,这种表示是通过外键约束来体现.本篇主要讲一对多的关系.先了解下描述关系的术 ...
- asp.net core系列 25 EF模型配置(隐藏属性)
一. 隐藏属性概述 隐藏属性也叫影子属性,该属性不是在.net实体类中定义的属性,而是在EFCore模型中为该实体类型定义的属性.这些属性的值和状态完全在变更跟踪器中维护.它有二个功能:(1)当数据库 ...
- asp.net core系列 24 EF模型配置(主键,生成值,最大长度,并发标记)
一.主键 键用作每个实体实例的主要唯一标识符. 使用关系数据库时,这会映射到主键的概念. 还可以配置不是主键的唯一标识符.按照约定,名为 Id 或 <type name>Id 的属性会配置 ...
- asp.net core系列 30 EF管理数据库架构--必备知识 迁移
一.管理数据库架构概述 EF Core 提供两种主要方法来保持 EF Core 模型和数据库架构同步.一是以 EF Core 模型为基准,二是以数据库为基准. (1)如果希望以 EF Core 模型为 ...
- asp.net core系列 31 EF管理数据库架构--必备知识 反向工程
一. 反向工程 反向工程是基于数据库架构,生成的实体类和DbContext类代码的过程,对于Visual Studio开发,建议使用PMC.对于其他开发环境,请选择.NET Core CLI工具( ...
- asp.net core 系列 22 EF(连接字符串,连接复原,DbContext)
一.连接字符串 在上二篇中,ASP.NET Core 应用程序连接字符串是写死在ConfigureServices代码中,下面介绍通过配置来实现.连接字符串可以存储在 appsettings.json ...
随机推荐
- xpath解析html
XPath XPath 是一门在 XML 文档中查找信息的语言.XPath 可用来在 XML 文档中对元素和属性进行遍历.XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XP ...
- Shell编程-控制结构 | 基础篇
if-then-else分支结构 if-then-else是一种基于条件测试结果的流程控制结构.如果测试结果为真,则执行控制结构中相应的命令列表:否则将进行另外一个条件测试或者退出该控制结构. if- ...
- ELK logstash geoip值为空故障排查
首先我们用的是elasticsearch+kibana+logstash+filebeat 客户端filebeat收集日志后经过服务端logstash规则处理后储存到elasticsearch中,在k ...
- git修改远程仓库关联
公司搬移, 作为git仓库的服务器IP地址变了. 本地代码挺多,重新检出太占时间,可以修改一个什么配置让我本地仓库和新的远程仓库建立关联吗, 答案是肯定的! 方法有很多,这里简单介绍几种: 以下均以项 ...
- 接口测试——postman & jmeter
新名词: 自动化测试:写代码帮你测试 接口:是一个抽象的概念,一种交互关系. 抓包:拦截请求. 接口测试:就是功能测试,比后者还简单. 需要有测试文档,包括项目.模块.URL.请求方式.参数.参数说明 ...
- php一些高级函数方法
PHP高级函数 1.call_user_func (http://php.net/manual/zh/function.call-user-func.php) 2.get_class (http:// ...
- MongoDB 用Robomong可视化工具操作的 一些简单语句
一.数据更新 db.getCollection('表名').update({ "字段":{$in:["值"]} }, //更新条件 {$set:{ " ...
- Address already in use: make_sock: could not bind to address 0.0.0.0:80
网上查了很多资料都是要杀进程,但是并没有找到占用的进程. 最后解决的方案是在apache配置文件下,去掉Listen 80 即可
- Best Cow Line---POJ 3617(贪心)
FJ is about to take his N (1 ≤ N ≤ 2,000) cows to the annual"Farmer of the Year" competiti ...
- post数据时报错:远程服务器返回错误: (400) 错误的请求。
网上查了多种方法,有不少说法,报400说是传的数据格式不对,最后的结论确实是数据格式不对. Content_Type为:application/json,配的数据格式有些麻烦,特别数多层,单层还好.例 ...