一对多关系配置
什么是实体间关系
1、所谓“关系数据库”
 2、复习:数据库表之间的关系: 一对一、一对多、多对多。
 3、EF Core不仅支持单实体操作,更支持多实体的关系操作。4、三部曲:实体类中关系属性;FluentAPI关系配置;使用关系操作。
一对多: 实体类
1、文章实体类Article、评论实体类Comment。一篇文章对应多条评论。
public class Article
{	public long Id { get; set;}public string Title( get; set;}public string Content{ get; set;}public List<Comment> Comments { get; set;}= new List<Comment>()
}
public class Comment
{public long Id { get; set; )public Article Article ( get; set; )public string Message ( get; set; )
}示例:
 新建Article类
 
新建Comment 类
 
一对一: 关系配置
EF Core中实体之间关系的配置的套路
 Hasxxx(…).Withxxx(…)
 有XXX、反之带有XXX
 XXX可选值One、Many
对多: HasOne(…).WithMany(…);
 一对一:HasOne(…).WithOne (…);
 多对多:HasMany (…).WithMany(…);
一对一: 关系配置
class ArticleConfig :IEntityTypeConfiguration<Article>
{public void Configure(EntityTypeBuilder<Article> builder){builder.ToTable("T Articles");builder.Property(a =>a.Content).IsRequired().IsUnicode();builder.Property(a =>a.Title).IsRequired().IsUnicode().HasMaxLength(255);}}一对多: 关系配置
class CommentConfig :IEntityTypeConfiguration<Comment>
{public void Configure(EntityTypeBuilder<Comment>builder){builder.ToTable("T_Comments");builder.HasOne<Article>(c=>c.Article).WithMany(a =>a.Comments).IsRequired();builder.Property(c=>c.Message).IsRequired0.IsUnicode();}}
引入包
 
新建ArticleConfig
 
新建CommentConfig
 
新建 myDbcontext

执行迁移命令
 
 
查看数据库
 

一对一: 试验
1、迁移生成数据库表。
 2、编写代码测试数据插入。
 3、不需要显式为Comment对象的Article属性赋值 (当前赋值也不会出错),也不需要显式地把新创建的Comment类型的对象添加到DbContext中。EF Core会顺竿爬”
示例:
 编写测试代码
 只需要将父对象 插入Dbcontext中 ,即可
 
运行:
 查看表数据
 
 
这样分别写也是同样的效果:
 
一对多关系数据的获取
获取关系数据
Article a =
ctx.Articles.Include(a=>a.Comments).Single(a=>aId==1);
Console.WriteLine(a.Title);foreach(Comment c in a.Comments)
{Console.WriteLine(c.Id+":"+c.Message);
}Include定义在Microsoft.EntityFrameworkCore命名空间中。
 查看一下生成的SQL语句
获取Id=2的 Article

 运行结果:
 
文章下的所有评论

 运行结果:
 
 没有comment内容
设置断点查看一下
 
 这种情况是不对的 ,按理应该有两条对应的评论
查看生成的sql语句,来查找问题所在
 
 发现只查询了T-Articles没有关联查询T-Comment
解决方法,加上 include
 表示插叙的时候,不仅查询Articles对应的表,也要关联查询Comment对应的表
修改之后
 
 运行结果:
 
 查看此时生成的sql语句
 
查询id=3对应的信息,以及文章信息

 
 发生异常
 TheArticle为null
 
 此时生成的sql语句,没有查询Article对应的数据表
 
要想查询到数据,同样要使用include
 
 此时运行结果:
 
 对应生成的sql语句
 
额外的外键字段
上述操作中不是已经有了一个TheArticleId外键字段了吗?
虽然生成了外键,但是Comment实体中并没有对应表中TheArticleId字段的字段。
 因为没有必要,TheArticle就能把对应的文章ID 取出来了
但是有的情况下,可能需要这一个属性,来单独获取外键值
为什么需要外键属性
1、EF Core会在数据表中建外键列。
 2、如果需要获取外键列的值,就需要做关联查询,效率低。试一下。
 3、需要一种不需要Join直接获取外键列的值的方式。
示例:
 查询TheArticle 必须使用 include 关键字,此时查询是通过inner join 连接,但是此时Comment表中,是应该有 TheArtice这个字段的,是不需要连表查询的
 
 生成的SQL语句
 
直接查询单表,就能查询到TheAricleId
 
方式一
首先,只想获取表中某些字段
 
 结果:
 
 运行的sql 语句
 
 发现他 查询了 Id,Message,Title 都查出来了,但是此时用不上Message
使用Select 的映射操作,只获取需要的类型

 此时,查看生成的SQL 语句

此时尝试,使用这种方式,能否获取到想要的数据,而不通过连表操作
 
 运行的SQL
 
 还是使用了连表查询
级联Select,获取数据,其实是不需要使用到include的,他是会在必要的使用自动加上include
 这里把 include 关键字去掉,再次尝试
 
 此时生成的SQL 语句 还是有 join 操作
 
正确的解决方法,单独给Comment 增加一个属性,和TheArticleI对应
 
 由于不会对数据库造成任何改变,此时不需要,在执行 迁移命令
 在关系中,告诉底层 ,新增的TheArticleId 就是外键列
 
此时修改代码
 
此时的sql 语句 便没有join操作
 
设置外键属性
1、在实体类中显式声明一个外键属性
 2、关系配置中通过HasForeignKey(c=>c.ArticleId)指定这个属性为外键。
 3、除非必要,否则不用声明,因为会引入重复
导航属性
由一个实体的属性,可以访问到另外一个实体的属性
 
 
 这两者 都是导航属性,这种两则对应的属于,双向导航属性
 
有时双向的麻烦
有时,一些基础表,可能被多次引用

 
示例:
新建User 类
 
 新建Leave类,请假
 
 配置表,UserConfig
 
 配置表 LeaveConfig
 
 配置DBContext
 
配置方法
不设置反向的属性,然后配置的时候WithMany0不设置参数即可

执行数据迁移命令
 
 
 查看数据库
 
 查询数据测试

 生成的sql语句
 
 插入语句测试
 
 数据库
 
选择
对于主从结构的“一对多”表关系,一般是声明双向导航属性。
 而对于其他的“一对多”表关系: 如果表属于被很多表引用的基础表,则用单项导航属性,否则可以自由决定是否用双向导航属性。
关系配置在任何一方都可以

反着配置也可以
CommentConfig:
 builder.HasOne
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/628578.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!