当前位置: 首页 > news >正文

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

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.hskmm.com/?act=detail&tid=12475

相关文章:

  • Java中异步任务的执行方式有几种?
  • 广二联考题解补全计划:
  • Chapter 8 Contour / Shape Detection
  • 【左程云算法笔记016】双端队列-双链表和固定数组实现 - 教程
  • java相关问题:面向对象入门2与类的识别
  • EXCEL自动调整列宽的快捷键
  • 【C++实战⑬】解锁C++文件操作:从基础到实战的进阶之路 - 实践
  • 破解塔吊顶升高危难题!让事故率降 50%、审批快 70%
  • logicFlow________文档2
  • CF2086D Even String
  • logicflow___文档3
  • 2025年运营商API安全建设最佳实践:某头部省级电信案例解析与方案推荐
  • 软件工程第二次作业-第一次个人编程作业
  • 面向对象入门2与类的识别
  • 202508_天山固网_to
  • jmeter分布式压测
  • 怎么屏蔽 ahref.com 上你不想看到的网站链接(垃圾外链)
  • 浅谈字典树
  • go-mapus为局域网地图协作而生
  • 《手搓动态顺序表:从数组到自动扩容的华丽转身》 - 详解
  • 板子大全
  • 通过人大金仓数据库的逻辑备份与还原功能实现数据迁移
  • 第十二节:订单普通下单、支付回调、退款、退款回调详解
  • 《原子习惯》-读书笔记7
  • 第3周预习作业
  • 《原子习惯》-读书笔记6
  • Java LTS版本进化秀:从8到21的欢乐升级之旅
  • 201912_EASER
  • 搜索百科(3):Elasticsearch — 搜索界的“流量明星”
  • 打印机漏洞、匿名协议与AWS安全:一周技术热点解析