EF循环依赖

2023-11-19

1.项目场景:

项目场景:

1.本项目采用了EF架构来建立实体与实体之间的关联关系。

2.一个部门对应多个摄像头

1.部门实体:

 public partial class DepartmentEntity		//部门实体
    { 
        public int Id { get; set; }
        public virtual ICollection< CameraEntity> lstCamera { get; set; }
        /// <summary>
        /// 部门编码
        /// </summary>
        public string DeptCode { get; set; }
        /// <summary>
        /// 部门名称
        /// </summary>
        public string DeptName { get; set; }
        /// <summary>
        /// 经度
        /// </summary>
        [DecimalPrecision(16, 8)]
        public decimal? Lon { get; set; }
        /// <summary>
        /// 纬度
        /// </summary>
        [DecimalPrecision(16, 8)]
        public decimal? Lat { get; set; }
    }

2.摄像头实体:

 public class CameraEntity		//摄像头实体
    {

        public int Id { get; set; }
        /// <summary>
        /// 摄像头名称
        /// </summary> 
        public string CameraName { get; set; }
        /// <summary>
        /// 所属部门Id
        /// </summary>
        public int? DeptId { get; set; }
        public virtual DepartmentEntity dept { get; set; }
        /// <summary>
        /// 经度
        /// </summary>
        [DecimalPrecision(16, 8)]
        public decimal? Lng { get; set; }
        /// <summary>
        /// 纬度
        /// </summary>
        [DecimalPrecision(16, 8)]
        public decimal? Lat { get; set; }

    }  

1.部门 mapping:

public class DepartmentEntityMapping : DataEntityTypeConfiguration<DepartmentEntity>
    {
        public DepartmentEntityMapping()
        {
         	//部门表
            ToTable("Department");		
            HasKey(t => t.Id);
            //一对多
            HasMany(x => x.lstCamera).WithOptional(z => z.dept).HasForeignKey(y=>y.DeptId);	
        }
    }

2.摄像头 mapping:

 public class CameraEntityMapping : DataEntityTypeConfiguration<CameraEntity>
    {
        public CameraEntityMapping()
        {
        	//AssetCameraInfo为数据库表名
            ToTable("AssetCameraInfo");		
            HasKey(t => t.Id);
            //一对多
            HasOptional(x => x.dept).WithMany().HasForeignKey(x => x.DeptId);	
        }
    }

1.controller层 – 调用该接口报错 – error:出现循环调用

 		/// <summary>
        /// 查摄像头集合
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [Route("TmpTest")]
        [HttpPost]
        [AllowAnonymous]
        public IHttpActionResult TmpTest([FromBody] QuerCameraInfo model)
        {
            TipsModel<List<CameraEntity>> tips = new TipsModel<List<CameraEntity>>(false);
            var lst = new AssetCameraInfoServiceV2().GetList(model);
            tips.SetResult(true, lst, "success");
            return Json(tips);
        }

2.Service层

public partial class AssetCameraInfoServiceV2
    {
        readonly Repository<CameraEntity> dao = new Repository<CameraEntity>();
 
        private IQueryable<BMS_D_AssetCameraInfoEntity> QueryCmd(QuerCameraInfo where)
        {
            var query = dao.Table;
            query = query.Where(x => x.DeleteState == 0);
            if (!where.CameraName.IsEmpty())
                query = query.Where(x => x.CameraName.Contains(where.CameraName));
            if (!where.DeptId.IsEmpty())
                query = query.Where(x => x.DeptId == where.DeptId);
            return query;
        }
        
        public List<CameraEntity> GetList(QuerCameraInfo where)
        {
            var temp = QueryCmd(where);
            return temp.ToList();
        }
	}

3.model 传参QuerCameraInfo

 public class QuerCameraInfo
    {
        public int Id { get; set; }
        /// <summary>
        /// 摄像头名称
        /// </summary> 
        public string CameraName { get; set; }
        /// <summary>
        /// 摄像头编码
        /// </summary>
        public string CameraCode { get; set; }
        /// <summary>
        /// 所属部门Id
        /// </summary>
        public int? DeptId { get; set; }
        public virtual DepartmentEntity dept { get; set; }
    }

2.报错内容

1.调用 controller层 的接口 TmpTest 报错如下:

"StatusCode": 408,
"OperateTime": "2022-09-08T14:56:58.9725345+08:00",
"Message": "2022年9月8日\tSelf referencing loop detected with type 'System.Data.Entity.DynamicProxies.BMS_D_AssetCameraInf_6940526873A10F06EF9B905552C9F9854FEA9BBA8CFBCCDBD1E36BF810A687E9'. Path 'ReturnValue[7].dept.lstCamera'.\t\n"

3.原因分析:

通过 GetList() 获得的 lst 集合中,每个相机实体中都有一个部门实体,每个部门中又有相机集合,故而出现死循环。


4.解决方案:

将 lst 转换为 model

1.controller层 – 分页查询camera

		/// <summary>
        /// 查询摄像头信息(分页)
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [Route("GetListCameraInfo")]
        [HttpPost]
        [AllowAnonymous]
        public IHttpActionResult GetListCameraInfo([JsonBinder] ElGrid grid)
        {
            TipsModel<ElGrid> tips = new TipsModel<ElGrid>(false);
            var where = grid.CreatePageBase<QuerCameraInfo>();
            AssetCameraInfoServiceV2 serveice = new AssetCameraInfoServiceV2();
            //转model
            tips.ReturnValue = grid.SetData(serveice.GetPageList(where), x => x.Select(y => y.ToModel()));
            //转model,model比entity多一个deptName字段
            tips.ReturnValue = grid.SetData(serveice.GetPageList(where), x => x.Select(y => y.ToInfoModel()));
            tips.IsSuccess = true;
            return Json(tips);
        }

5.补充信息

每个 AutoMapper 都对应一个 Profile

1.CameraInfoModel

public class CameraInfoModel
    {
        public int Id { get; set; }
        /// <summary>
        /// 摄像头名称
        /// </summary> 
        public string CameraName { get; set; }
        /// <summary>
        /// 所属部门Id
        /// </summary>
        public int? DeptId { get; set; }
        /// <summary>
        /// 部门名称
        /// </summary>
        public string DeptName { get; set; }
        /// <summary>
        /// 经度
        /// </summary>
        [DecimalPrecision(16, 8)]
        public decimal? Lng { get; set; }
        /// <summary>
        /// 纬度
        /// </summary>
        [DecimalPrecision(16, 8)]
        public decimal? Lat { get; set; }
   }
  1. AutoMapperExcetions 中的 CameraMapper
 #region	摄像头信息表 CameraEntity
        public static CameraInfoModel ToInfoModel(this CameraEntity entity)
        {
            return entity.MapTo<CameraEntity, CameraInfoModel>();
        }
        public static CameraEntity ToInfoEntity(this CameraInfoModel model)
        {
            return model.MapTo<CameraInfoModel, CameraEntity>();
        }
#endregion

3.CameraProfile.cs
将 entity 转换为 CameraInfoModel, 其中根据 deptId 获取部门名称放在 CameraInfoModel 中进行输出.

 private void CameraProfile() {
            CreateMap<CameraInfoModel, CameraEntity>();
            CreateMap<CameraEntity, CameraInfoModel>()
                .ForMember(x => x.DeptName, y => y.MapFrom(z => z.dept == null ? "" : z.dept.DeptName));
        }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EF循环依赖 的相关文章

随机推荐

  • Logback 自定义Appender发送预警

    1 自定义Appender 目的 接收日志消息 现将日志通过http接口发送到预警服务 package com test service appender import ch qos logback classic spi LoggingE
  • Unity -Input

    Unity Input详解 Unity中的InputManager输入控制器 Input属性方法详解 属性 方法 Unity中的InputManager输入控制器 Name 按键名 该键的名称 可以在脚本编程中直接引用他 比如 Input
  • 硬件基础之集成运放

    一 技术理论 1 集成电路 集成电路是采用专门的制造工艺 在半导体单晶硅上 把晶体管 场效应管 二极管 电阻和电容等元器件以及它们之间的连线所组成的电路制作在一起 使其具有特定功能的芯片 2 集成运放 集成运放 全称集成运算放大器 是具有超
  • 部署多台服务器,动态配置前端请求的ip地址

    需求 前后端分离的项目 需要部署多台服务器 但是不想频繁修改前端配置的ip地址 故需要需要动态配置 解决 发送请求时的url默认获取服务器的ip function getBaseUrl const url location href toS
  • 深入剖析Nginx日志:常用分析技巧汇总

    前言 本来只是想写一篇Nginx日志的常用统计分析命令填充一下线上文档 虽然有点用但是觉得光写命令 文档太水了 于是就顺便总结一下 在nginx或web服务中 需要有哪些进行分析的内容以及为什么有这些需求 ps 统计命令的原因 在于不是每个
  • 杨桃的Python进阶讲座18——数组array(八)如何从一维数组扩展为二维数组以及再次降为一维数组

    本人CSDN博客专栏 https blog csdn net yty 7 Github地址 https github com yot777 用reshape 函数将一维数组升维成二维数组 首先我们由一个列表转换为NpArray数组 gt g
  • git 提交代码时,提示输入用户名和密码,不知道用户名和密码是啥

    最近在跟小伙伴一起做小项目玩 之前clone代码时都是ssh 这次用的是https 提交代码遇到问题 在网上没有查到解决问题的办法 所以在这里记录以下这个问题的解决办法 后续有时间要 熟练掌握 git的使用方法 当小伙伴再遇到问题时 就可以
  • vue中如何引入jquery详解

    用vue cli脚手架工具构建项目成功后 当需要引入JQ 可用以下方法 1 首先在package json里的dependencies加入 jquery 3 2 1 2 在终端里输入npm install jquery save dev 当
  • unity 读取和写入Excel中文出现乱码解决方法

    在编辑器中读取和写入中文一切正常 发布出来只要是中文就会出现乱码 解决方法 将C Program Files Unity Editor Data Mono lib mono unity 目录下的I18N dll和I18N CJK dll复制
  • [转载]搜索引擎技术介绍

    转载声明 http backend blog 163 com blog static 202294126201252872124208 引言 早些时候分享过一份关于搜索引擎技术的PPT 这篇文章基本上是基于原来框架 在内容上做了一些改进和扩
  • 清华镜像pip安装命令

    在ubuntu系统下 pip3 install 安装包的名字 i https pypi tuna tsinghua edu cn simple 永久设置 pip install pip U pip config set global ind
  • 哈工大 csapp lab5

    实验报告 实 验 五 题 目 LinkLab 链接 专 业 计算机科学与技术 学 号 190110812 班 级 7 学 生 刘新晨 指 导 教 师 吴锐 实 验 地 点 G707 实 验 日 期 2021 5 16 计算机科学与技术学院
  • Linux 常用命令介绍

    文章目录 1 初级 1 pwd命令 2 cd命令 3 ls命令 实例练习 2 中级 1 Linux文件操作 1 创建文件 2 删除文件 2 Linux文件夹操作 1 创建文件夹 2 删除文件夹 3 Linux文件和文件夹拷贝 4 Linux
  • 使用 cloc 统计你的代码量

    转自 使用 cloc 统计你的代码量 今天发现一个特别好用的工具 cloc 可以用它统计代码的行数 它可以识别多种开发语言 并在计算的时候忽略掉注释和空行 我记得我上次申请软件著作权的时候 申请表格中要求提交代码量 当时为了计算行数 我写了
  • 51单片机——LED点阵屏

    51单片机 LED点阵屏 LED点阵屏 LED点阵屏原理 74HC595串转并芯片 源代码 例程一 静态笑脸 效果展示 例程二 笑脸 gt 平脸 gt 哭脸 效果展示 LED点阵屏 c51的LED点阵屏其实就是一个8 8像素的屏幕 一共有6
  • Qt程序的编译和发布(实验报告)

    实验 1 编译和发布 Qt 程序 目的与要求 掌握创建 Qt 程序的方法 掌握发布 Qt 程序的方法 学会为 Qt 程序添加应用程序图标 了解 Qt 发布需要的 DLL 动态库文 实验准备 搭建好 Qt 开发环境 了解 Qt Creator
  • 如何查看当前使用的Shell类型

    1 在终端输入命令 echo SHELL echo SHELL 2 在终端输入命令 echo 0 数字0 这个命令不是所有Shell都支持 echo 0 3 在终端输入命令ps 查看当前运行的shell是什么 如图1所示 有一个进程是bas
  • 【react】新旧生命周期对比

    componentWillUpdate componentWillReceiveProps componentWillMount 上述这三个生命周期在V18以上的版本中 使用时要加上UNSELF name
  • php正则表达式 验证密码,用于强密码验证的PHP正则表达式

    参见英文答案 gt Reference Password Validation 1个 我在网上看到了以下正则表达式 8 d W n A Z a z 它只在字符串中有效 contain at least 1 upper case letter
  • EF循环依赖

    1 项目场景 项目场景 1 本项目采用了EF架构来建立实体与实体之间的关联关系 2 一个部门对应多个摄像头 1 部门实体 public partial class DepartmentEntity 部门实体 public int Id ge