02020403 EF Core基础03-Fluent API、Data Annotation、两种配置的选择

news/2025/9/21 21:23:26/文章来源:https://www.cnblogs.com/python-web/p/19104194

02020403 EF Core基础03-Fluent API、Data Annotation、两种配置的选择

1. FluentAPI哪些不该用(视频3-4)

1.1 约定配置
主要规则:
1:表名采用DbContext中的对应的DbSet的属性名。
2:数据表列的名字采用实体类属性的名字,列的数据类型采用和实体类属性类型最兼容的类型。
3:数据表列的可空性取决于对应实体类属性的可空性。
4:名字为Id的属性为主键,如果主键为short, int 或者 long类型,则默认采用自增字段,如果主键为Guid类型,则默认采用默认的Guid生成机制生成主键值。
1.2 DbSet属性名作为数据表名
// Dog.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EFCoreDemo
{public class Dog{public long Id { get; set; } //主键public string Name { get; set; }//标题}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// DbContext.cs
using Microsoft.EntityFrameworkCore;namespace EFCoreDemo
{class MyDbContext : DbContext{public DbSet<Book> Books { get; set; }public DbSet<Person> Persons { get; set; }public DbSet<Dog> Dogs { get; set; } // @1protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connStr = "Server=.;Database=CoreDataDB;Trusted_Connection=True;MultipleActiveResultSets=true";optionsBuilder.UseSqlServer(connStr);}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}说明:在@1处,因为Dog实体类没有配置DogConfig配置类,此时数据库中创建的表名称为Dogs,与DbSet属性对应。
1.3 两种配置方式
1、Data Annotation
把配置以特性(Annotation)的形式标注在实体类中。
[Table("T_Books")]
public class Book
{
}
优点:简单;缺点:耦合。
2、Fluent API
builder.ToTable("T_Books");
把配置写到单独的配置类中。
缺点:复杂;优点:解耦
3、大部分功能重叠。可以混用,但是不建议混用。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 使用Fluent API存到不同的数据库
if(mysql)
{builder.ToTable("T_Persons");
}
else(sql server)
{builder.ToTable("Persons")
}说明:
1. Fluent API形式可以解耦,而Data Annotation无法实现。
2. 实际开发中,推荐使用Fluet API的形式。因为开发中,各种奇葩需求层出不绝。
3. 本课程除了特殊的地方,老师采用Fluent API形式配置数据库。
1.4 Fluent API配置形式
  • 在02020401和02020402中创建的数据表采用的是Fluent API的形式。
1.5 Data Annotation配置形式
// Cat.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;namespace EFCoreDemo
{[Table("T_Cats")]class Cat{public long Id { get; set; } //主键[Required] // 不可为空[MaxLength(22)] // 最大长度22public string Name { get; set; }//标题}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// MyDbContext.cs
using Microsoft.EntityFrameworkCore;namespace EFCoreDemo
{class MyDbContext : DbContext{public DbSet<Cat> Cats { get; set; }protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){string connStr = "Server=.;Database=CoreDataDB;Trusted_Connection=True;MultipleActiveResultSets=true";optionsBuilder.UseSqlServer(connStr);}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}}
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 程序包资源管理器控制台:
PM> add-migration add_cat
Build started...
Build succeeded.
To undo this action, use Remove-Migration.
PM> update-database
Build started...
Build succeeded.
Applying migration '20250919133837_add_cat'.
Done.
PM> 说明:此时会生成T_Cats,并有设定的配置。
  • 执行上述代码,在SSMS中生成的表如下
图片链接丢失
1.6 课外探讨(仅供参考)
  • A、B两个技术,如果A比B适度且合理复杂,那么尽量选A。
    • 要尽量选稍微复杂一点的。
    • 做项目会发现,一开始简单的,最后会把你坑的要死。

2. Fluent API基础特性

1、视图与实体类映射:modelBuilder.Entity<Blog>().ToView("blogsView");
2、排除属性映射:
modelBuilder.Entity<Blog>().Ignore(b => b. Name2);
3、配置列名:默认是实体类的属性名,也可以配置为其它名称。
modelBuilder.Entity<Blog>().Property(b =>b.BlogId).HasColumnName("blog_id");
4、配置列数据类型:
builder.Property(e => e.Title) .HasColumnType("varchar(200)")
5、配置主键
默认把名字为Id或者“实体类型+Id“的属性作为主键,可以用HasKey()来配置其他属性作为主键。modelBuilder.Entity<Student>().HasKey(c => c.Number);
支持复合主键,但是不建议使用。
6、生成列的值
modelBuilder.Entity<Student>().Property(b => b.Number).ValueGeneratedOnAdd();
7、可以用HasDefaultValue()为属性设定默认值
modelBuilder.Entity<Student>().Property(b => b.Age).HasDefaultValue(6);
8、索引
modelBuilder.Entity<Blog>().HasIndex(b => b.Url);
复合索引
modelBuilder.Entity<Person>().HasIndex(p => new { p.FirstName, p.LastName });
唯一索引:IsUnique();聚集索引:IsClustered()
9...  用EF Core太多高级特性的时候谨慎,尽量不要和业务逻辑混合在一起,以免“不能自拔”。比如Ignore、Shadow、Table Splitting等……说明:
1. Dapper简单、入门快、生产效率低。
2. EF Core复杂、生产效率高。但是不要用EF Core很多复杂的高级特性,要让EF Core用的更像Dapper一些。
2.1 让EF Core生产效率稍微低一点,但是更加简单。
2.2 不要陷入EF Core复杂的高级特性中不能自拔。
3. 根据实际开发经验,找到Dapper和EF Core之间的平衡点。

3. Fluent API中的方法(视频3-5)

3.1 Fluent API众多方法
Fluent API中很多方法都有多个重载方法。比如HasIndex、Property()。
把Number属性定义为索引,下面两种方法都可以:
builder.HasIndex("Number");
builder.HasIndex(b=>b.Number);推荐使用HasIndex(b=>b.Number)、Property(b => b.Number)这样的写法,因为这样利用的是C#的强类型检查机制
3.2 Property的重载方法
// Person.cs
namespace EFCoreDemo
{public class Person{public long Id { get; set; }public long Name { get; set; }public int Age { get; set; } public string BirthPlace { get; set; } public double? Salary { get; set; } }
}
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// PersonConfig.cs
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;namespace EFCoreDemo
{class PersonConfig : IEntityTypeConfiguration<Person>{public void Configure(EntityTypeBuilder<Person> builder){builder.Property(b => b.Name).HasDefaultValue("Qinway"); // @1 Lambda表达式写法builder.Property("Name").HasDefaultValue("YZK"); // @2 采用属性名的写法builder.HasKey(b => b.Id); // 推荐的Lambda写法builder.HasKey("Id"); // 不推荐的属性写法}}
}说明:
1. 推荐用@1处的写法。这样可以通过Tab自动完成,同时还可以使用类型检查机制。
2. 比如在@1处,b.Name写成了b.Name3,编译器会报错。而在@2处"Name"写成了"Name3",编译器不会报错。
3.3 Fluent API的对比写法
// 标准写法:3条语句
builder.ToTable("T_Books");
builder.HasIndex(b => b.Title);
builder.Ignore(b => b.PubTime);
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 正确写法:2条语句
builder.ToTable("T_Books").HasIndex(b => b.Title);
builder.Ignore(b => b.PubTime);<= 上述写法与下面写法等价 =>EntityTypeBuilder<Book> etbBook = builder.ToTable("T_Books");
etbBook.HasIndex(b => b.Title);
builder.Ignore(b => b.PubTime);说明
1. Fluent API不管怎么写,必须符合C#的语法。
2. ToTable方法的返回值类型为EntityTypeBuilder类型,HasIndex方法是EntityTypeBuilder类的方法,因此可以.下去。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
// 错误写法:1条语句
builder.ToTable("T_Books").HasIndex(b => b.Title).Ignore(b => b.PubTime);说明:
1. Ignore()不是HasIndex的属性或者方法,因此不能.了。
2. 可以调整Ignore()和HasIndex()的顺序,可能不会报错。
—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—·—
综上:
1. 对于表的配置写一行。
2. 对于属性写一行。
3. 对于索引写一行。

4. Data Annotation和Fluent API的选择

1、Data Annotation 、Fluent API大部分功能重叠。可以混用,但是不建议混用。
2、有人建议混用,即用了Data Annotation 的简单,又用到Fluent API的强大,而且实体类上标注的[MaxLength(50)]、[Required]等标注可以被ASP.NET Core中的验证框架等复用。我为什么不建议混用。
3、我和业界很多人都倾向只使用Fluent API。本课以讲解Fluent API为主(尽量用约定),如果项目强制用Data Annotation 请翻文档,知识都是通用的。

结尾

书籍:ASP.NET Core技术内幕与项目实战

视频:https://www.bilibili.com/video/BV1pK41137He

著:杨中科

ISBN:978-7-115-58657-5

版次:第1版

发行:人民邮电出版社

※敬请购买正版书籍,侵删请联系85863947@qq.com※

※本文章为看书或查阅资料而总结的笔记,仅供参考,如有错误请留言指正,谢谢!※

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909060.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入解析:Python(1)|| 超基础语法(格式,输入输出,变量,字符串,运算符)

深入解析:Python(1)|| 超基础语法(格式,输入输出,变量,字符串,运算符)2025-09-21 21:23 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflo…

深入解析:STM32-FreeRTOS操作系统-任务管理

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Java中异步任务的执行方式有几种?

在Java中,异步任务的执行方式有多种,每种方式适用于不同的场景和需求。以下是常见的几种实现方式:Thread类 最基础的方式是直接使用Thread类创建线程执行任务:new Thread(() -> {// 异步执行的任务System.out.p…

mysql数据库自增ID为int类型超过范围

mysql数据库自增ID为int类型超过范围mysql数据的自增加的id(int)类型,超过范围:数据自增加ID,为int类型,超过范围,就插入数据库失败;怎么解决? 由于数据比较大, 1.第一个简单粗暴:把int变为(BIGINT)不用迁…

202508_浙江省网络安全测试职业职工技能竞赛_misc-1

流量分析,RE,XORTags:流量分析,RE,XOR 0x00. 题目 你是一名资深的网络安全分析取证师,受命调查一家IT公司近期遭遇的一起严重网络安全事件。 该公司主要业务是为中小型企业提供定制化管理系统和数据分析服务。 由…

python爬虫测试

python爬虫测试0.背景:要下合适自己的驱动,不然都是报错!!你需要完成以下两步:检查你的 Chrome 浏览器版本。打开 Chrome,在地址栏输入 chrome://settings/help。 你会看到你的 Chrome 版本号,例如 版本 120.0.…

广二联考题解补全计划:

第十七套: T1:取模性质,倍增 T2: DP优化,状态优化 T3:容斥原理,数位DP T1: 首先先提一个关于取模的性质,一个数对一个比它小的数取模,大小一定减半,考虑对 $ \frac {n}{2}$ 分治即可。 我们先预处理出来每个数…

如何在 C# 中将文本转换为 Word 以及将 Word 转换为文本 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Chapter 8 Contour / Shape Detection

def getContours(img):contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)for cnt in contours:area = cv2.contourArea(cnt)print(area)if area > 500:# -1 代表所有的轮廓c…

【左程云算法笔记016】双端队列-双链表和固定数组实现 - 教程

【左程云算法笔记016】双端队列-双链表和固定数组实现 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Cons…

LeetCode 几道 Promises 和 Time 的题目 - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

[硬件电路-232]:FET(场效应管)的核心机制是通过栅极电压调控半导体“沟道“中的载流子浓度与分布,进而控制源极与漏极之间的电流大小 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

java相关问题:面向对象入门2与类的识别

1. 关于 static 修饰符 应该用 static 修饰的方法: *不依赖于特定对象的实例状态:执行的操作不访问或修改对象的实例变量。 *工具类方法:常用于定义工具类中的方法,这些方法提供通用功能,无需创建类实例。 *工厂方…

EXCEL自动调整列宽的快捷键

在 Excel 中,自动调整列宽的快捷键是:Windows 系统:先选中要调整的列(可选中单列或多列),然后按下 Alt + H + O + I(依次按下这些键)。 Mac 系统:先选中要调整的列,然后按下 Command + Option + H + O + I。…

【C++实战⑬】解锁C++文件操作:从基础到实战的进阶之路 - 实践

【C++实战⑬】解锁C++文件操作:从基础到实战的进阶之路 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Co…

破解塔吊顶升高危难题!让事故率降 50%、审批快 70%

在建筑施工领域,塔吊顶升作业作为关键且高危的环节,长期以来饱受诸多痛点的困扰,严重影响施工安全与进度。传统模式下,人工对塔吊顶升作业的审查多依赖现场巡检,然而人力有限,在忙碌的施工现场,难以做到时刻紧盯…

logicFlow________文档2

# LogicFlow 官方指南 - 自定义连线与事件处理## 📖 概述LogicFlow 是滴滴开源的一款流程图编辑框架,具有强大的扩展性和自定义能力。本文档基于LogicFlow官网最新版本,详细介绍如何实现自定义连线、自定义事件处理…

CF2086D Even String

题目链接:Problem - D - Codeforces 本身是一道数学题,我们可以把字符串中的奇数项和偶数项分开,形成两条序列 A 和 B。易知一种字母一定在同一条序列上。 假如说在 A 序列上分配了 \(a,b,c\) 三种字母,\(sum = c_…

logicflow___文档3

# LogicFlow 流程图编辑器开发文档## 📖 概述这是一个基于 LogicFlow 的流程图编辑器完整开发指南,包含详细的代码示例和实现方案。该编辑器支持节点创建、连接线绘制、关系管理等功能。## 🚀 快速开始### 1. 安装…

langraph-up-react

langraph-up-react https://github.com/fanqingsong/langraph-up-reactLangGraph ReAct Agent TemplateThis template showcases a ReAct agent implemented using LangGraph, works seamlessly with LangGraph Studio…