实体是我们对现实世界业务的抽象,对于C#开发者来讲,我们使用面向对象的思维用类的形式去将它表示出来。
使用EF Core
可以将实体中表达的含义,转化为数据库存储的结构。
关于实体定义的规范和约定,我们要结合语言的表现能力以及EF Core
的特性,给出一些建议。
遵循Entity Framework Core
的官方文档,对模型及关联关系进行定义。
EF Core提供了三种方式来补充与数据库相关的信息,这些信息并不是业务实体所必须的,如:
我们可以通过数据注释
,Fluent API
的方式来设定这些信息,
如官方文档:实体属性所示。
使用数据注释
,是指在实体模型类当中添加特性,这意味着实体模型类同时也包含数据库相关的信息。
使用Fluent API
,则可以把实体跟数据库相关的表述内容分开。如果按照这种方式,在OnModelCreating
中的代码会越来越多,且可读性较差。
由于Fluent API
的一些问题,EF Core
也提供了IEntityTypeConfiguration
接口,称为分组配置
,
具体可参考官方文档:分组配置。
建议使用统一的方式去定义数据库元数据,如统一使用数据注释
或分组配置
,部分功能使用Fluent API
。
Note
Fluent API
能实现很多功能,且它的优先级更高,在定义全局过滤等需求中,还是非常适合使用的。
我们知道C#现在有了很多定义数据结构的方法,Class
,Record
,Struct
等等,在语言层面上,他们各有不同,很多人可能会有些困惑,我应该使用什么方式去定义更好。
根据官方给出的示例和我们的实践,在此给出一些建议:
class
去定义实体模型类required
关键字(.NET7/C#11新关键词)表示必填字段,避免使用[Required]特性EF Core
以及一些类型转换器的行为。示例:
/// <summary> /// 项目信息 /// </summary> public class ProjectInfo { // 使用required限定必填内容,不使用[required]或构造方法限定 public required string Name { get; set; } // 同时使用init,表示值必须在初始化时填入,后续无法修改,也不需要使用构造方法限定 public required string Path { get; init; } public ProjectType ProjectType { get; set; } = ProjectType.Web; }
内容大纲