EF中Fluent API更多配置

基本EF配置只要配置实体类和表、字段的对应关系、表间关联关系即可。如果利用EF的高级配置,可以达到更多效果:如果数据错误(比如字段不能为空、字符串超长等),会在EF层就会报错,而不会被提交给数据库服务器再报错;如果使用自动生成数据库,也能帮助EF生成更完美的数据库表。

基本步骤

在StudentConfig,实体对象的配置类中去设置指定的字符的其他配置

  1. 首先调用Property()方法获取目标字段
  2. Property()方法中使用的是Lambda表达式
  3. 获取到字段之后调用一系列EF函数设置字段的配置

字段的最大长度

HasMaxLength设定字段的最大长度
例如设置表中的Name的字段最大长度为50

 this.Property(p=>p.Name).HasMaxLength(50);

如果插入一个Person对象,Name属性的值非常长,保存的时候就会报DbEntityValidationException异常,这个异常的Message中看不到详细的报错消息,要看EntityValidationErrors属性的值。

字段是否可空

 this.Property(p => p.Pwd).IsRequired();//不为空
  this.Property(p => p.Pwd).IsOptional();//可为空(没用的鸡肋!)

EF默认规则是“主键属性不允许为空,引用类型允许为空,可空的值类型long?等允许为空,值类型不允许为空。”基于“尽量少配置”的原则:如果属性是值类型并且允许为null,就声明成long?等,否则声明成long等;如果属性属性值是引用类型,只有不允许为空的时候设置IsRequired()。

其他一般不用设置的

  1. 主键:this.HasKey(p => p.pId);
  2. 某个字段不参与映射数据库:this.Ignore(p => p.Name1);
  3. this.Property(p => p.Name).IsFixedLength(); 是否对应固定长度
  4. this.Property(p => p.Name).IsUnicode(false) 对应的数据库类型是varchar类型,而不是nvarchar
  5. this.Property(p => p.Id).HasColumnName(“Id”); Id列对应数据库中名字为Id的字段
  6. this.Property(p=>p.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity) 指定字段是自动增长类型。

流动起来

因为ToTable()、Property()、IsRequired()等方法的还是配置对象本身,因此可以实现类似于StringBuilder的链式编程,这就是“Fluent”一词的含义;

一对多关系映射

EF最有魅力的地方在于对于多表间关系的映射,可以简化工作。 复习一下表间关系:

  1. 一对多(多对一):一个班级对应着多个学生,一个学生对着一个班级。一方是另外一方的唯一。在多端有一个指向一端的外键。
    举例:
    班级表:T_Classes(Id,Name)
    学生表T_Students(Id,Name,Age,ClassId)
  2. 多对多:一个老师对应多个学生,一个学生对于多个老师。任何一方都不是对方的唯一。 需要一个中间关系表。
    具体:
    学生表T_Students(Id,Name,Age,ClassId)
    老师表 T_Teachers(Id,Name,PhoneNum)
    关系表T_StudentsTeachers(Id,StudentId,TeacherId)

和关系映射相关的方法

  1. 基本套路this.Has(p=>p.A).With***() 当前这个表和A 属性的表的关系是Has 定义, With 定义的是A 对应的表和这个表的关系。Optional/Required/Many
  2. HasOptional() 有一个可选的(可以为空的)
  3. HasRequired() 有一个必须的(不能为空的)
  4. HasMany() 有很多的
  5. WithOptional() 可选的
  6. WithRequired() 必须的
  7. WithMany() 很多的

配置一对多关系

  1. 先按照正常的单表配置把Student、ClassRoom 配置起来,Students 的ClassId 字段就对应Student类的ClassId 属性。
  2. 给Student类增加一个ClassRoom类型、名字为CRoom(不一定非叫这个,但是习惯是:外键名去掉Id)的属性,要声明成virtual(后面讲原因)
  3. 然后就可以实现各种对象间操作了:
    数据插入也变得简单了,不用再考虑“先保存Class,生成Id,再保存Student”了。这样就是纯正的“面向对象模型”,ClassId 属性可以删掉。
  4. 如果ClassId 字段可空怎么办?直接把ClassId 属性设置为long?
  5. 还可以在Class中配置一个public virtual ICollection Students { get; set; } = new List(); 属性。最好给这个属性初始化一个对象。注意是virtual。这样就可以获得所有指向了当前对象的Stuent集合,也就是这个班级的所有学生。我个人不喜欢这个属性,业界的大佬也是建议“尽量不要设计双向关系”,因为可以通过Class clz = ctx.Classes.First(); var students =ctx.Students.Where(s => s.ClassId == clz.Id);来查询获取到,思路更清晰。
已标记关键词 清除标记
相关推荐
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质? 你是否想成为一名资深开发人员,想开发别人做不了的高性能程序? 你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹?   那么C++就是你个人能力提升,职业之路进阶的不二之选。 【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。 2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。 3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。 【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署; 2.吊打一切关于C++的笔试面试题; 3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。 【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块 基础篇 本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。 进阶篇 本篇主要讲解编程常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。 提升篇: 本篇可以帮助学员更加高效的进行c++开发,其包含类型转换、文件操作、异常处理、代码重用等内容。
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:C马雯娟 返回首页