(22)ASP.NET Core EF创建模型(索引、备用键、继承、支持字段)
1.索引
索引是跨多个数据存储区的常见概念。尽管它们在数据存储中的实现可能会有所不同,但也可用于基于列(或一组列)更高效地进行查找。
1.1约定
按照约定,将在用作外键的每个属性(或一组属性)中创建索引。
1.2数据批注
不能使用数据批注创建索引。
1.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);
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
您还可以指定索引应是唯一的,这意味着对于给定的属性,不能有两个实体具有相同的值。
modelBuilder.Entity<Blog>()
.HasIndex(b => b.Url)
.IsUnique();
您还可以为多个列指定索引。
class MyContext : DbContext
{
public DbSet<Person> People { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>()
.HasIndex(p => new { p.FirstName, p.LastName });
}
}
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
2.备用键
备用键与主键相对,用作每个实体实例的备用唯一标识符。备用键可用作关系的目标。使用关系数据库时,这将映射到备用键列上的唯一索引/约束和引用列的一个或多个外键约束的概念。系统通常会在需要时为你引入备用键,你无需手动配置它们。
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)
.HasForeignKey(p => p.BlogUrl)
.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; }
}
2.2数据注释
不能使用数据注释配置备用键。
2.3Fluent API
你可以使用熟知的API将单个属性配置为备用密钥。
class MyContext : DbContext
{
public DbSet<Car> Cars { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
//配置为备用密钥
.HasAlternateKey(c => c.LicensePlate);
}
}
class Car
{
public int CarId { get; set; }
public string LicensePlate { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
你还可以使用熟知的API将多个属性配置为备用密钥(称为复合备用键)。
class MyContext : DbContext
{
public DbSet<Car> Cars { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
//配置为备用密钥
.HasAlternateKey(c => new { c.State, c.LicensePlate });
}
}
class Car
{
public int CarId { get; set; }
public string State { get; set; }
public string LicensePlate { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
3.继承
EF模型中的继承用于控制如何在数据库中表示实体类中的继承。
3.1约定
按照约定,由数据库提供商确定如何在数据库中表示继承。有关如何使用关系数据库提供程序来处理此情况的详细说明。如果模型中显式包括两个或更多个继承类型,则EF仅会设置继承。EF不会扫描模型中未包含的基类型或派生类型。可以通过为继承层次结构中的每个类型公开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; }
}
如果不想公开层次结构中一个或多个实体的DbSet,可以使用熟知的API来确保它们包含在模型中。如果不依赖约定,则可以使用HasBaseType显式指定基类型。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<RssBlog>().HasBaseType<Blog>();
}
}
4.支持字段
支持字段允许EF读取和写入字段,而不是属性。当使用类中的封装来限制或通过应用程序代码对数据访问进行限制时,这可能很有用,但在不使用这些限制的情况下,应从数据库中读取或写入值。
4.1约定
按照约定,将发现以下字段作为给定属性的支持字段(按优先级顺序列出)。仅为模型中包含的属性发现字段。
public class Blog
{
private string _url;
public int BlogId { get; set; }
public string Url
{
get { return _url; }
set { _url = value; }
}
}
配置了支持字段后,当从数据库具体化实体实例(而不是使用属性资源库)时,EF将直接写入该字段。如果EF需要在其他时间读取或写入值,则它将使用属性(如果可能)。例如,如果EF需要更新某个属性的值,则它将使用属性setter(如果已定义)。如果该属性为只读,则它将写入字段。
4.2数据注释
不能通过数据批注配置支持字段。
4.3Fluent API
你可以使用熟知的API来配置属性的支持字段。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.HasField("_validatedUrl");
}
}
public class Blog
{
private string _validatedUrl;
public int BlogId { get; set; }
public string Url
{
get { return _validatedUrl; }
}
public void SetUrl(string url)
{
using (var client = new HttpClient())
{
var response = client.GetAsync(url).Result;
response.EnsureSuccessStatusCode();
}
_validatedUrl = url;
}
}
4.3.1控制何时使用字段
可以配置EF何时使用字段或属性。有关支持的选项,请参阅PropertyAccessMode枚举。
modelBuilder.Entity<Blog>()
.Property(b => b.Url)
.HasField("_validatedUrl")
.UsePropertyAccessMode(PropertyAccessMode.Field);
4.3.2没有属性的字段
你还可以在你的模型中创建一个概念属性,该属性在实体类中不具有相应的CLR属性,而是使用字段来存储实体中的数据。这不同于阴影属性,其中的数据存储在更改跟踪器中。如果实体类使用方法获取或设置值,通常会使用此方法。可以在Property(...) API中为EF指定字段的名称。如果没有具有给定名称的属性,则EF将查找字段。
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property("_validatedUrl");
}
}
public class Blog
{
private string _validatedUrl;
public int BlogId { get; set; }
public string GetUrl()
{
return _validatedUrl;
}
public void SetUrl(string url)
{
using (var client = new HttpClient())
{
var response = client.GetAsync(url).Result;
response.EnsureSuccessStatusCode();
}
_validatedUrl = url;
}
}
您还可以选择为属性指定名称,而不是字段名称。然后,在创建模型时使用此名称,最值得注意的是,该名称将用于在数据库中映射到的列名称。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Property<string>("Url")
.HasField("_validatedUrl");
}
如果实体类中没有属性,则可以在LINQ查询中使用EF.Property(...)方法来引用概念上是模型的一部分的属性。
var blogs = db.blogs.OrderBy(b => EF.Property<string>(b, "Url"));
(22)ASP.NET Core EF创建模型(索引、备用键、继承、支持字段)的更多相关文章
- (21)ASP.NET Core EF创建模型(关系)
1.关系 关系定义两个实体之间的关系.在关系型数据库中,这由外键约束表示. 2.术语定义 有许多术语用于描述关系:●相关实体:这是包含外键属性的实体.有时称为关系的"子级".●主体 ...
- (19)ASP.NET Core EF创建模型(包含属性和排除属性、主键、生成的值)
1.什么是Fluent API? EF中内嵌的约定将POCO类映射到表.但是,有时您无法或不想遵守这些约定,需要将实体映射到约定指示外的其他对象,所以Fluent API和注解都是一种方法,这两种方法 ...
- (20)ASP.NET Core EF创建模型(必需属性和可选属性、最大长度、并发标记、阴影属性)
1.必需和可选属性 如果实体属性可以包含null,则将其视为可选.如果属性的有效值不可以包含null,则将其视为必需属性.映射到关系数据库架构时,必需的属性将创建为不可为null的列,而可选属性则创建 ...
- asp.net core系列 27 EF模型配置(索引,备用键,继承)
一.索引 索引是许多数据存储中的常见概念.虽然它们在数据存储中的实现可能会有所不同,但它们可用于更有效地基于列(或列集)进行查找.按照约定,用作外键每个属性 (或组的属性) 会自动创建索引.无法使用数 ...
- C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现之方法二:加入缓存机制
在上一篇文章中我用递归方法实现了管理菜单,在上一节我也提到要考虑用缓存,也算是学习一下.Net Core的缓存机制. 关于.Net Core的缓存,官方有三种实现: 1.In Memory Cachi ...
- 创建ASP.NET Core MVC应用程序(5)-添加查询功能 & 新字段
创建ASP.NET Core MVC应用程序(5)-添加查询功能 & 新字段 添加查询功能 本文将实现通过Name查询用户信息. 首先更新GetAll方法以启用查询: public async ...
- asp.net core+ef core
asp.net core+ef core 官方的文档https://docs.asp.net/en/latest/tutorials/first-mvc-app/start-mvc.html 先来看一 ...
- 002.Create a web API with ASP.NET Core MVC and Visual Studio for Windows -- 【在windows上用vs与asp.net core mvc 创建一个 web api 程序】
Create a web API with ASP.NET Core MVC and Visual Studio for Windows 在windows上用vs与asp.net core mvc 创 ...
- 使用 ASP.NET Core MVC 创建 Web API(四)
使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...
随机推荐
- 05.Django基础五之django模型层(一)单表操作
一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...
- Hadoop集群常用的shell命令
Hadoop集群常用的shell命令 Hadoop集群常用的shell命令 查看Hadoop版本 hadoop -version 启动HDFS start-dfs.sh 启动YARN start-ya ...
- 夯实Java基础系列11:深入理解Java中的回调机制
目录 模块间的调用 多线程中的"回调" Java回调机制实战 实例一 : 同步调用 实例二:由浅入深 实例三:Tom做题 参考文章 微信公众号 Java技术江湖 个人公众号:黄小斜 ...
- java架构之路-(面试篇)JVM虚拟机面试大全
下文连接比较多啊,都是我过整理的博客,很多答案都在博客里有详细说明,理解记忆是最扎实的记忆.而且我的答案不一定是最准确的,但是我的答案不会让你失望,而且几乎每个答案都是问题的扩展答案. 1.JVM内存 ...
- Java基础学习笔记(六) - 数据结构和集合
一.认识数据结构 1.数据结构有什么用? 合理的使用数据结构,可以更方便的查找存储数据. 2.常见的数据结构 数据存储常用结构有:栈.队列.数组.链表和红黑树. 栈:堆栈(stack),它是运算受限的 ...
- 本次作业统一标题:C语言I博客作业02
这个作业属于哪个课程 C语言程序设计1 这作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-2/homework/8655 我在这个课程的目标是 ...
- Ubuntu部署Tomcat Web服务
在Ubuntu平台中安装TomCat 本文将为大家介绍TomCat在Ubuntu平台中如何进行部署使用,带你快速入门使用TomCat TomCat简介 Tomcat是Apache 软件基金会(Apac ...
- ELK日志分析系统(4)-elasticsearch数据存储
1. 概述 logstash把格式化的数据发送到elasticsearch以后,elasticsearch负责存储搜索日志数据 elasticsearch的搜索接口还是很强大的,这边不详细展开,因为k ...
- python编程基础之三十七
数据的持久化:数据持久化就是将内存中的对象转换为存储模型,以及将存储模型转换为内存中的对象的统称. 对象可以是任何数据结构或对象模型,存储模型可以是关系模型.XML.二进制流等 Python的数据持久 ...
- 【TencentOS tiny】深度源码分析(3)——队列
队列基本概念 队列是一种常用于任务间通信的数据结构,队列可以在任务与任务间.中断和任务间传递消息,实现了任务接收来自其他任务或中断的不固定长度的消息,任务能够从队列里面读取消息,当队列中的消息是空时, ...