efcore 6.0 从属实体
注意:本文描述的是一对一的从属实体(一对多也差不多,只是略有差别,具体可参见MSDN中的EFCORE6.0的文章),也就是一行对应一行。
概念
- 普通从属实体
就是多个实体类型映射1个数据库表,每个实体包含不同的字段属性。
例如:一张表不重要的字段太多,并不是每次查询都需要那么多字段,如果按照常规一个实体类映射一张表,那么每次都要处理那么多字段太麻烦,所以干脆分成两个实体,一个实体包含重要字段,另一个实体包含其他字段作为从属实体即可。 - 映射独立数据表的从属实体
从属实体也可以单独映射另一张数据库表 ,这种场景也是较常见的,
例如:已经在使用的数据库表,你只是想要自定义增加一些扩展字段,而且不便在原表上增加字段。这时候就需要新增一张新表,那么这个新增表就可以作为从属实体进行映射。
普通从属实体(与主实体映射同一张数据表)
做法很简单,例如如下数据库表:
表名:Person
id | name | age | sex | createTime | updateTime |
---|---|---|---|---|---|
1 | 张三 | 20 | 男 | 2020-01-01 | 2022-01-02 |
2 | 李四 | 21 | 男 | 2018-12-22 | 2022-04-02 |
3 | 韩梅梅 | 23 | 女 | 2021-03-11 | 2021-03-12 |
4 | lucy | 24 | 女 | 2019-03-15 | 2022-11-22 |
5 | lily | 24 | 女 | 2021-11-6 | 2022-03-26 |
假设,灰色部分createTime、updateTime俩字段为不常用字段,那么可以分成两个实体进行映射。
主实体类代
码:
public class Person{public int ID { get; set; } public string? name { get; set; } public int age { get; set; } public string? sex { get; set; } //新建一个导航属性,类型名即是【从属实体类名】,本例为:PersonOtherspublic PersonOthers personOthers1 { get; set; } }
从属实体类
代码:
[Owned] //从属实体类要加[Owned]注释public class PersonOthers{ //与引用导航、集合导航的表连接等不同。从属实体根本不需要任何主键、外键(例如:不需要定义个ID属性与主实体Persen的ID属性连接),直接把指定的字段映射上就好了。public Datetime CreateTime { get; set; }public Datetime UpdateTime { get; set; } }
其实到这里从属实体已经建立完成了,但是,查询时系统会把从属实体的映射字段名强制识别为加统一前缀(例如本例会被识别为:personOthers1_CreateTime,personOthers1_UpdateTime),这样显然是不正确的 。所以必须用Fluent API手动配置映射字段名 ,Fluent API代码如下:
public partial class myContext : DbContext{//..............public virtual DbSet<Persen> Persens { get; set; } = null!;protected override void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.Entity<Persen>(entity =>{ entity.HasKey(m => m.ID);entity.ToTable("Person"); //........................................//以下为从属实体代码-------------------entity.OwnsOne(p => p.personOthers1, x =>{ x.Property(p => p.CreateTime).HasColumnName("createTime");x.Property(p => p.UpdateTime).HasColumnName("updateTime"); } );//从属实编辑结束 -----------------------------}} }
映射单独表的从属实体(与主实体映射不同的数据表)
数据库表如下
主表表名:Person
id | name | age | sex |
---|---|---|---|
1 | 张三 | 20 | 男 |
2 | 李四 | 21 | 男 |
3 | 韩梅梅 | 23 | 女 |
4 | lucy | 24 | 女 |
5 | lily | 24 | 女 |
但是主表本身没有创建时间和更新时间的字段,所以必须增加一个包含这俩字段的新表。这时候,新表就必须要有外键了(新表中只要有表示外键的字段即可,未必要在数据库中定义关系,在Fluent API中配置外键也可以)
新表表名:Persentime
pid | createTime | updateTime |
---|---|---|
1 | 2020-01-01 | 2022-01-02 |
2 | 2018-12-22 | 2022-04-02 |
3 | 2021-03-11 | 2021-03-12 |
4 | 2019-03-15 | 2022-11-22 |
5 | 2021-11-6 | 2022-03-26 |
假设,新表ID的字段名为pid,与主表的主键字段名id不同。
主实体和从属实体类代码跟上面一样即可,唯一区别是从属实体类要加一个pid属性作为外键:
[Owned] //从属实体类要加[Owned]注释public class PersonOthers //从属类名还是叫PersonOthers也无妨,可以在Fluent API中配置映射表名为Persontime即可。{ //如果从属实体映射一张单独的数据表, 那么必须有一个外键字段,本例中为pid。public int Pid { get; set; } public Datetime CreateTime { get; set; }public Datetime UpdateTime { get; set; } }
可以在Fluent API中配置:
public partial class myContext : DbContext{//..............public virtual DbSet<Persen> Persens { get; set; } = null!;protected override void OnModelCreating(ModelBuilder modelBuilder){modelBuilder.Entity<Persen>(entity =>{ entity.HasKey(m => m.ID);entity.ToTable("Person"); //........................................//以下为从属实体代码-------------------entity.OwnsOne(p => p.personOthers1, x =>{ x.ToTable("Persontime"); //personOthers1映射的数据库表名x.WithOwner ().HasForeignKey (t=>t.Pid ) //从属实体的外键 .HasPrincipalKey (p=>p.ID ); //主实体具有唯一特性的字段(如果这个字段是主实体的主键,那么这句可以省略,例如本例就可以省略。)x.Property(t => t.Pid).HasColumnName("pid"); //x.Property(t => t.CreateTime).HasColumnName("createTime");x.Property(t => t.UpdateTime).HasColumnName("updateTime"); } );//从属实体编辑结束 -----------------------------}} }
总结
普通从属实体
和映射单独表的从属实体
的区别就是:
映射单独表的从属实体
在实体类中需要定义一个外键属性,而普通从属实体
不用。映射单独表的从属实体
在Fluent API配置中需要指定从属实体的外键
、主实体的唯一键(如果是主键则不用)
,而普通从属实体
不用。
除此之外,两者都一样。
注意:不管是是否映射独立表,从属实体只能在主实体的modelBuilder.Entity< T >中进行配置,不能定义独立的modelBuilder.Entity< T >; 也不能注册一个自己的DbSet< T >。否则会报错,因为从属实体的意思就是主实体的附属实体,不允许单独使用
efcore 6.0 从属实体相关推荐
- [Asp.net mvc]实体更新异常:存储区更新、插入或删除语句影响到了意外的行数(0)。实体在加载后可能被修改或删除。
学习asp.net mvc 时在更新实体进行SaveChanges()的时候出现了异常,异常如下: 存储区更新.插入或删除语句影响到了意外的行数(0).实体在加载后可能被修改或删除.刷新 Object ...
- 数据库分析与设计练习题(二)基础知识、在IDEF0需求建模方法中,下列关于描述功能活动的图示,正确的是、事务详细编码设计是在下列哪个阶段完成的、下列关于从属实体集的描述,错误的是、各事务尽量按照相同的
17.在数据库系统生命周期中,通过系统规划与定义来明确系统的目标任务.下列不属于系统规划与定义内容的是 A确定成本预算 B确定任务目标 C确定用户视图 D确定系统边界 参考答案为A 解析:系统规划与定 ...
- 脱虚向实,NGK公链让工业4.0赋能实体
工业4.0是以广泛的工业自动化.高带宽行动网络的兴起,以及物联网(IoT)的发展为标志的最新趋势,而区块链(blockchain)在工业4.0中将有各种潜在应用. 区块链特殊的链接价值的发展方式和体制 ...
- EF更新或者删除的时候报错“存储区更新、插入或删除语句影响到了意外的行数(0)。实体在加载后可能被修改或删除“
ScheduleDown表 主键: ① 字段为MachineNum,类型为String . ②字段ScheduleStart,类型为DateTime. using (MESDB db = new ME ...
- 存储区更新、插入或删除语句影响到了意外的行数(0)。实体在加载后可能被修改或删除。
描述:一般出现这个问题,就是在进行操作数据时,对象的ID的毛病.我遇见这个错误就是在对User表进行操作的时候,没有考虑到ID,直接对对象进行操作,报了上述的错误. 错误原因:如果我们没有ID对我们的 ...
- 存储区更新、插入或删除语句影响到了意外的行数(0)。实体在加载后可能被修改或删除。有关了解和处理乐观并发异常的信息
在使用EF更新数据库内容的时候,提示这个错误 原因:找不到主键,因为我数据库设置的name为主键,切试图更改name的值 解决方法:将数据库的id设为主键,传值的时候不需要传id
- 存储区更新、插入或删除语句影响到了意外的行数(0)。实体在加载后可能被修改或删除
有没有大佬帮忙解决问题谢谢?.
- excel能设置从属值集吗_Excel中的从属组合框
excel能设置从属值集吗 You can add a drop down list in a worksheet cell, so people can select from a list of ...
- .NET EFCore之增删改查
1. 连接数据库 通过依赖注入配置应用程序,通过startup类的ConfigureService方法中的AddDbContext将EFCore添加到依赖注入容器 public void Config ...
最新文章
- Linux脚本关联,shell数组和关联数组
- Windows Azure Platform Introduction (9) 申请Windows Azure 账户
- gerrit的git配置流程
- [Qt教程] 第24篇 数据库(四)SQL查询模型QSqlQueryModel
- oracle查询中表的连接顺序 手工指定
- mysql数据库主从不同步_mysql数据库主从不同步的解决方法
- 对atexit函数的理解
- web项目开发最佳做法
- jvm入门到详解-1
- Linux文件与目录的三种时间状态(mtime,atime,ctime)区别
- gc计算机术语,GC是什么意思?
- 《Python编程从入门到实践》(第2版)第二章 习题答案
- 修改电脑开机徽标教程
- Python项目通用的目录结构总结
- 【TouchDesigner】Feedback的应用NO.3
- ASO优化|标题、描述、关键词的最优策略
- 毕业季租房的攻略来啦
- Python学习,元类type 反射 函数与方法 双下方法
- php carbon 中文,Carbon中文使用手册(下)
- 计算广告第一章——在线广告综述