EntityFramework Core 学习系列(一)Creating Model
EntityFramework Core 学习系列(一)Creating Model
Getting Started
使用Command Line 来添加 Package
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
使用 -v
可以指定相应包的版本号。
使用dotnet ef
命令
需要在.csproj
文件中包含下面引用
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0"/>
</ItemGroup>
Creating a Model
Fluent API
在继承至 DbContext
的子类中,重载 OnModelCreating() 方法进行Fluent API 的配置。
public class MyDbContext : DbContext
{
//...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<TEntity>()
.Property(b => b.Url)
.IsRequired();
//...
}
//...
}
Data Annotation
或者可以使用数据注解直接在实体中进行配置:
public class Blogs
{
public string BlogName { get; set; }
[Required]
public string Url { get; set; }
}
关于配置的顺序规范,
Fluent API > Data Annotations > Conventions
Include & Exclude
有下列三种情况类或实体会被包含:
- By convention, types that are exposed in
DbSet
properties on your context are included in your model. - Types that are mentioned in the
OnModelCreating
method are also included. - Any types that are found by recursively exploring the navigation properties of discovered types are also included in the model.
你可以通过 Data Annotation 或者 Fluent API 来 排除包含,示例如下:
//Data Annotations Example Below:
public class Blogs
{
public int BlogId { get; set;}
public BlogAuthor BlogAuthors { get; set;}
}
[NotMapped]
public class BlogAuthor
{
public string FirstName { get; set;}
//...
}
//Fluent API Example Below:
public class MyDbContext : DbContext
{
public DbSet<Blog> Blogs { get; set;}
protected override OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Ignore<BlogAuthor>();
}
}
public class Blogs
{
public int BlogId { get; set;}
public BlogAuthor BlogAuthors { get; set;}
}
public class BlogAuthor
{
public string FirstName { get; set;}
//...
}
当然除了可以排出/包含类之外, 还可以自己配置相应的属性如下:
//Data Annotations Example Below:
public class Blogs
{
public int BlogId { get; set;}
public BlogAuthor BlogAuthors { get; set;}
[NotMapped]
public DateTime BlogAddedTime { get; set;}
}
//Fluent API Example Below:
public class MyDbContext : DbContext
{
public DbSet<Blog> Blogs { get; set;}
protected override OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.Ignore(b => b.BlogAddedTime);
}
}
public class Blogs
{
public int BlogId { get; set;}
public BlogAuthor BlogAuthors { get; set;}
public DateTime BlogAddedTime { get; set;}
}
Key
关于EF Core 中的Key, 按照规范,如果一个属性命名为Id 或者 以Id结尾的都会被配置成该实体的主键。比如下面的这个:
public class TestClass
{
public int Id { get; set; }
//or
public int MyId { get; set; }
}
或者你可以按照 Data Annotation 或者 Fluent API 来进行配置:
// Data Annotations
public class Car
{
[Key]
public string CarLicense { get; set; }
public string CarFrameCode { get; set;}
}
//Fluent API
//...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Car>()
.HasKey(c => c.CarLicense);
}
//...
// Multiple Properties to the key ,复合主键的配置只能用Fluent API
modelBuilder.Entity<Car>()
.HasKey(c => new { c.CarLicense, c.CarFrameCode });
Generated Values
中文应该是叫值的自动生成
吧,我也不清楚。EF Core
上 有三种 Value Generation Pattern。分别是
No Value Generation
No value generation means that you will always supply a valid value to be saved to the database. This valid value must be assigned to new entities before they are added to the context.
值不自动生成,每个属性的值都需要指定,添加。这个我理解的意思应该是你保存到数据库里面的值,每个必须是有效的,并且需要指定。
Value Generated on Add
Value generated on add means that a value is generated for new entities.
Depending on the database provider being used, values may be generated client side by EF or in the database. If the value is generated by the database, then EF may assign a temporary value when you add the entity to the context. This temporary value will then be replaced by the database generated value during
SaveChanges()
.If you add an entity to the context that has a value assigned to the property, then EF will attempt to insert that value rather than generating a new one. A property is considered to have a value assigned if it is not assigned the CLR default value (
null
forstring
,0
forint
,Guid.Empty
forGuid
, etc.).属性的值在 添加到数据库时自动添加。
Value Generated on Add or Update
Value generated on add or update means that a new value is generated every time the record is saved (insert or update).
Like
value generated on add
, if you specify a value for the property on a newly added instance of an entity, that value will be inserted rather than a value being generated. It is also possible to set an explicit value when updating.属性的值在 添加到数据库或者更新时自动添加。
当当看着上面这三个,我其实并不知道这三个到底是什么意思,接下来会用例子来演示一下这些具体意思,以及使用规范。
By convention, primary keys that are of an integer or GUID data type will be setup to have values generated on add. All other properties will be setup with no value generation.(当主键为 Interger 或者 GUID类型事,该主键的值会自动生成。)
下面用实例来模拟一下:
我们新建一个实体 Blogs 如下:
//Entity Blog
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
// Program.cs
using (var db = new BookDbContext())
{
if (!db.Blogs.Any())
{
var blog = new Blog
{
Url = "Https://q.cnblogs.com"
};
db.Blogs.AddRange(blog);
db.SaveChanges();
}
}
直接用在Program 用using 来演示效果,由于我们之前说到的主键为 Integer 类型的会自动生成值,所以数据库中的值大家可想而知,就是下面这个
下面是用Data Annotation(数据注解)来演示的,也可以用Fluent API:
No Value Generation
如果我们不想让它自动生成的话呢,也有办法。向下面这样:
public class Blog
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int BlogId { get; set; }
public string Url { get; set; }
}
我在 BlogId 上加上 DatabaseGeneratedOption.None 之后,我们再重新运行上面的程序,发现数据库的值如下所示:
为什么是 0 的原因呢,其实上面已经解释过了:就是下面这句话
A property is considered to have a value assigned if it is not assigned the CLR default value (
null
forstring
,0
forint
,Guid.Empty
forGuid
, etc.). CLR 的默认值。
Fluent API 版本
modelBuilder.Entity<Blog>()
.Property(b => b.BlogId)
.ValueGeneratedNever();
Value Generated on Add
比如我们还想在 Blog 实体里面加一个 更新时间 UpdateTime 属性
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
[DataGenerated(DatabaseGeneratedOption.Identity)]
public DateTime UpdateTime { get; set;}
}
当我们配置成上面这样,然后直接 dotnet run 时,发现程序报错了。
Unhandled Exception: Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> Microsoft.Data.Sqlite.SqliteException: SQLite Error 19: 'NOT NULL constraint failed: Blogs.UpdateTime'.
在Setting Explicit Value 中在OnModelCreating 中配置,使其自动生成,但是本地我使用SQLite 时无法自动生成,报错。具体使用如下
modelBuilder.Entity<Blog>()
.Property(p => p.UpdateTime)
.HasDefaultValueSql("CONVERT(date, GETDATE())");
Fluent API 版本
modelBuilder.Entity<Blog>()
.Property(b => b.UpdateTime)
.ValueGeneratedOnAdd();
Value generated on add or update (Data Annotations)
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime LastUpdated { get; set; }
}
Fulent API 版本
modelBuilder.Entity<Blog>()
.Property(b => b.LastUpdated)
.ValueGeneratedOnAddOrUpdate();
下面记录一下 dotnet ef 命令的使用
dotnet ef migrations add name
dotnet ef database update
dotnet ef migrations remove
dotnet ef database drop
EntityFramework Core 学习系列(一)Creating Model的更多相关文章
- ASP.NET Core学习系列
.NET Core ASP.NET Core ASP.NET Core学习之一 入门简介 ASP.NET Core学习之二 菜鸟踩坑 ASP.NET Core学习之三 NLog日志 ASP.NET C ...
- EntityFramework Core 学习笔记 —— 创建模型
原文地址:https://docs.efproject.net/en/latest/modeling/index.html 前言: EntityFramework 使用一系列的约定来从我们的实体类细节 ...
- EntityFramework Core 学习扫盲
0. 写在前面 1. 建立运行环境 2. 添加实体和映射数据库 1. 准备工作 2. Data Annotations 3. Fluent Api 3. 包含和排除实体类型 1. Data Annot ...
- Net core学习系列(一)——Net Core介绍
一.什么是Net Core .NET Core是适用于 windows.linux 和 macos 操作系统的免费.开源托管的计算机软件框架,是微软开发的第一个官方版本,具有跨平台 (Windows. ...
- EntityFramework Core 学习笔记 —— 添加主键约束
原文地址:https://docs.efproject.net/en/latest/modeling/keys.html Keys (primary) Key 是每个实体例的主要唯一标识.EF Cor ...
- 【.Net Core 学习系列】-- EF Core 实践(Code First)
一.开发环境: VS2015, .Net Core 1.0.0-preview2-003156 二解决方案: 新建项目: File --> New --> Project --> ...
- 【.Net Core 学习系列】-- EF Core实践(DB First)
一.开发环境: VS2015, .Net Core 1.0.0-preview2-003156 二.准备数据: CREATE DATABASE [Blogging]; GO USE [Blogging ...
- Net core学习系列(八)——Net Core日志
一.简介# 日志组件,作为程序员使用频率最高的组件,给程序员开发调试程序提供了必要的信息.ASP.NET Core中内置了一个通用日志接口ILogger,并实现了多种内置的日志提供器,例如 Conso ...
- Net core学习系列(四)——Net Core项目执行流程
"跨平台"后的ASP.Net Core是如何接收并处理请求的呢? 它的运行和处理机制和之前有什么不同?本章从"宏观"到"微观"地看一下它的结 ...
随机推荐
- Beta总结篇
45°炸 031502601 蔡鸿杰 031502604 陈甘霖 031502632 伍晨薇 一.项目预期进展及现实进展 项目预期计划 现实进展 Github使用 √ 日拍 (调用相机.相册) √ 足 ...
- 2017-2018-1 Java演绎法 第一周 作业
团队学习:<构建之法> [团队成员]: 学号 姓名 负责工作 20162315 马军 日常统计,项目部分代码 20162316 刘诚昊 项目部分代码,代码质量测试 20162317 袁逸灏 ...
- 20162318 实验四 Android程序设计
北京电子科技学院(BESTI) 实 验 报 告 课程:程序设计与数据结构 班级:1623班 姓名:张泰毓 指导老师:娄老师.王老师 实验日期:2017年5月26日 实验密级:非密级 实验器材:带Lin ...
- Linux 复习
shift + control + + 终端窗口放大 control + - 终端窗口缩小 ls -alh > laowang.txt 重定向,并覆盖源文件内容 ls -alh >& ...
- pickle使用及案例
一.字典格式数据源写入数据库文件 #!/usr/bin/env python # -*- coding:utf-8 -*- import pickle accounts ={1000:'alex', ...
- LR回放https协议脚本失败: 错误 -27778: 在尝试与主机“www.baidu.com”connect 时发生 SSL 协议错误
今天用LR录制脚本协议为https协议,回放脚本时出现报错: Action.c(14): 错误 -27778: 在尝试与主机"www.baidu.com"connect 时发生 S ...
- react基础篇入门组件
讲述一下React: 1.声明式设计-React采用声明范式,可以轻松描述应用 2.高效-React通过DOM模型,最大限度的减少dom的交互 3.灵活-React可以与已知的库或框架很好的配合 4. ...
- 微信公众号Markdown编辑器, 适合代码排版
随着大家都转战微信公众平台,如何快速的编写文章就摆在了首要位置.不可否认,使用微信自带的编辑器可以做出好看的排版,甚至用第三方编辑器有更多的模板.但是,这些全部都需要手动的调整.本来公众平台就算是自媒 ...
- Golang学习--平滑重启
在上一篇博客介绍TOML配置的时候,讲到了通过信号通知重载配置.我们在这一篇中介绍下如何的平滑重启server. 与重载配置相同的是我们也需要通过信号来通知server重启,但关键在于平滑重启,如果只 ...
- php的set_time_limit()函数
set_time_limit(0); 括号里边的数字是执行时间,如果为零说明永久执行直到程序结束,如果为大于零的数字,则不管程序是否执行完成,到了设定的秒数,程序结束. 一个简单的例子,在网页里显示1 ...