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

在EFCore中,我何时需要在值对象中添加[Owned]特性?

报错内容:System.InvalidOperationException:“The entity type 'xxx' cannot be configured as owned because it has already been configured as a non-owned. If you want to override previous configuration first remove the entity type from the model by calling 'Ignore'.

原因:我在实体中添加了一个值对象。值对象如下:

有一个枚举类型的属性Weekday,由于显式得未配置 [Owned] 特性 导致报错 

    public class WeeklyLoopTimeStamp:ValueObject{// 日期public DayOfWeek Weekday{get; set;}// 时间public DateTime TimePoint{get; set;}protected override IEnumerable<object> GetAtomicValues(){yield return Weekday;yield return TimePoint;}}

 

在EF Core中,当你想要将属性标记为值对象,并且希望EF Core将其配置为复合类型(Complex Type)时,你需要在值对象的属性上添加[Owned]特性。

添加[Owned]特性的好处是,EF Core会自动处理该属性与其所属实体之间的映射和关系。它简化了代码,并减少了手动配置的工作量。

然而,并非所有情况下都需要添加[Owned]特性。以下是一些情况说明:

1. 当属性的数据类型本身是一个简单的值类型(如string、int、DateTime等)时,EF Core会自动将其视为复合类型的一部分,无需添加[Owned]特性。

2. 当属性的数据类型是自定义的类或结构体,并且你希望将其视为独立的实体类型(拥有自己的唯一标识符),而不是复合类型时,你不需要添加[Owned]特性。

3. 当属性是一个集合类型(如List、ICollection等)时,EF Core会自动将其配置为导航属性,不需要添加[Owned]特性。

所以,只有当你确实希望将属性配置为值对象并作为复合类型存储在同一个数据库表中时,才需要在值对象的属性上添加[Owned]特性。

如果没有添加[Owned]特性而不报错,很可能是由于EF Core的默认行为能够正确地推断出属性应该被视为复合类型。然而,为了明确你的意图并提高代码的清晰度,建议在值对象的属性上显式添加[Owned]特性

拓展问题:

1. 值对象在数据表中以何种结构被存储?

在数据库中,如果一个实体拥有一个值对象属性,通常会将该值对象的属性作为实体表中的进行存储。

简单理解为:值对象的属性会被提取到实体属性中,从而成为单独的一列

对于你提到的WxTemplateForPlanOrderEntity实体,如果WeeklyLoopTimeStamp是一个值对象属性,那么通常会根据数据库的设计,创建一个包含WeeklyLoopTimeStamp属性的列。

具体地,可以根据你所使用的数据库类型和ORM框架的要求,将WeeklyLoopTimeStamp属性的值序列化为适当的数据类型(例如字符串、JSON等),并将其存储在数据库表的相应列中。

例如,在关系型数据库中,你可以将WeeklyLoopTimeStamp属性的值以JSON格式序列化,并将其存储为varchar或json类型的列。在NoSQL数据库中,可能会选择直接将WeeklyLoopTimeStamp属性的值存储为文档或字段的形式。

需要注意的是,数据库中的列与实体的属性之间需要进行映射关系的配置。这通常由ORM框架负责处理,通过特定的注解、配置文件或代码来定义实体属性与数据库列之间的映射关系。

综上所述,数据库的存储方式取决于数据库类型、ORM框架和相关配置,但一般来说,值对象属性会被作为实体表中的单独列进行存储。

2. 如果实体下的值对象是一对多关系?数据表中会如何存储?

例子:

    /// <summary>/// 发送数据时机 按周循环/// </summary>public List<WeeklyLoopTimeStamp> WeeklyLoopTimeStamp{get;set;}

那么需要根据ORM来配置,一般会创建一张另外的关联表。外键与实体相关联。

builder.OwnsMany( );

具体传入的配置方法需要根据项目规范制定。

相关文章:

  • git解决冲突
  • [PTP][1588v2] Delay_Resp消息
  • ubuntu0.22.04.1安装mysql8.0及root密码注意
  • C++:OJ练习(每日练习系列)
  • 使用JAVA语言写一个排队叫号的小程序
  • 《QDebug 2023年11月》
  • 鸿蒙开发笔记
  • docker 推送tar包到远程仓库
  • LeetCode(43)快乐数【哈希表】【简单】
  • vue 路由跳转到其他页面指定位置(锚点)
  • golang 函数选项模式
  • MySQL 大表设计
  • ARM与大模型,狭路相逢
  • 阿里云国际短信业务网络超时排障指南
  • IP地址更改的方法及注意事项,让你的网络更安全稳定
  • 分享的文章《人生如棋》
  • DOM的那些事
  • JavaScript异步流程控制的前世今生
  • Java精华积累:初学者都应该搞懂的问题
  • markdown编辑器简评
  • mysql_config not found
  • node和express搭建代理服务器(源码)
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • React-flux杂记
  • ReactNativeweexDeviceOne对比
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 从PHP迁移至Golang - 基础篇
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 分布式事物理论与实践
  • 聚簇索引和非聚簇索引
  • 使用docker-compose进行多节点部署
  • 数组大概知多少
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • k8s使用glusterfs实现动态持久化存储
  • 函数计算新功能-----支持C#函数
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • # dbt source dbt source freshness命令详解
  • #android不同版本废弃api,新api。
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (阿里云万网)-域名注册购买实名流程
  • (初研) Sentence-embedding fine-tune notebook
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • *1 计算机基础和操作系统基础及几大协议
  • .bat批处理(五):遍历指定目录下资源文件并更新
  • .helper勒索病毒的最新威胁:如何恢复您的数据?
  • .naturalWidth 和naturalHeight属性,
  • .NET Core 中的路径问题