【golang-ent】go-zero框架 整合 ent orm框架 | 解决left join未关联报错的问题

一、场景

1、子表:cp_member_point_history

cp_member_point_history表中字段:cp_point_reward_id 是cp_point_reward的主键id

当本表中的cp_point_reward_id字段为0(即:没有可关联主表的)

sql 复制代码
CREATE TABLE `cp_member_point_history` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `point` int DEFAULT NULL COMMENT '获取积分',
  `cp_point_reward_id` bigint DEFAULT NULL COMMENT '外键 cp_point_reward 主键id',
  `show_status` tinyint(1) DEFAULT NULL COMMENT '是否删除:0、可用,1:删除',
  `updated_at` datetime DEFAULT NULL COMMENT '更新时间',
  `created_at` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户积分变更历史';

2、主表:cp_point_reward

sql 复制代码
CREATE TABLE `cp_point_reward` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `point` int DEFAULT NULL COMMENT '消耗积分',
  `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '奖品名称',
  `reward` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '奖品说明',
  `reward_status` int DEFAULT NULL COMMENT '1:上架、2:下架(默认是1)',
  `show_status` tinyint(1) DEFAULT NULL COMMENT '是否删除:0、可用,1:删除',
  `updated_at` datetime DEFAULT NULL COMMENT '更新时间',
  `created_at` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='积分奖品';

3、golang 使用 ent 源码

当 左连接 WithCpPointRewardMPH()时,无法进行关联时,则下面循环时,直接报错panic

go 复制代码
package cpMemberPointHistory

import (
	"context"
	"fmt"
	"github.com/suyuan32/simple-admin-common/utils/pointy"
	"github.com/zeromicro/go-zero/core/logx"
)

type GetCpMemberPointHistoryListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetCpMemberPointHistoryListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetCpMemberPointHistoryListLogic {
	return &GetCpMemberPointHistoryListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetCpMemberPointHistoryListLogic) GetCpMemberPointHistoryList(in *cpgobusiness.CpMemberPointHistoryListReq) (*cpgobusiness.CpMemberPointHistoryListResp, error) {
	var predicates []predicate.CpMemberPointHistory
	if in.CpMemberId != nil {
		predicates = append(predicates, cpmemberpointhistory.CpMemberID(*in.CpMemberId))
	}
	if in.CpPointRewardId != nil {
		predicates = append(predicates, cpmemberpointhistory.CpPointRewardID(*in.CpPointRewardId))
	}
	if in.CpResourceId != nil {
		predicates = append(predicates, cpmemberpointhistory.CpResourceID(*in.CpResourceId))
	}

	result, err := l.svcCtx.DB.CpMemberPointHistory.Query().Where(predicates...).
		WithCpMemberMPH().
		WithCpPointRewardMPH().
		WithCpResourceMPH().Page(l.ctx, in.Page, in.PageSize, func(pager *ent.CpMemberPointHistoryPager) {
		pager.Order = ent.Desc(cpmemberpointhistory.FieldID)

	})

	if err != nil {
		return nil, dberrorhandler.DefaultEntError(l.Logger, err, in)
	}

	resp := &cpgobusiness.CpMemberPointHistoryListResp{}
	resp.Total = result.PageDetails.Total

	for _, v := range result.List {
		Template := &cpgobusiness.CpMemberPointHistoryInfo{
			Id:              &v.ID,
			CreatedAt:       pointy.GetPointer(v.CreatedAt.UnixMilli()),
			UpdatedAt:       pointy.GetPointer(v.UpdatedAt.UnixMilli()),
			ShowStatus:      pointy.GetPointer(int64(v.ShowStatus)),
			CpMemberId:      &v.CpMemberID,
			Point:           &v.Point,
			ChangeType:      &v.ChangeType,
			CpResourceId:    &v.CpResourceID,
			CpPointRewardId: &v.CpPointRewardID,
			GainType:        &v.GainType,
			Name:            &v.Edges.CpMemberMPH.Name,
			Phone:           &v.Edges.CpMemberMPH.Phone,
			NickName:        &v.Edges.CpMemberMPH.NickName,
			Gender:          &v.Edges.CpMemberMPH.Gender,
			PointName:       pointy.GetPointer(""),
			ResourceTitle:   &v.Edges.CpResourceMPH.Title,
		}
		if v.Edges.CpPointRewardMPH != nil {
			fmt.Println("------------ v.Edges.CpPointRewardMPH.Name:", v.Edges.CpPointRewardMPH.Name)
			Template.PointName = &v.Edges.CpPointRewardMPH.Name
		}
		resp.Data = append(resp.Data, Template)
	}

	return resp, nil
}

4、解决方案

问题:

报错的位置在:&v.Edges.CpPointRewardMPH.Name

因为 v.Edges.CpPointRewardMPHnil

解决

先判断 v.Edges.CpPointRewardMPH 是否为空

如果不为空,则赋值

go 复制代码
if v.Edges.CpPointRewardMPH != nil {
	fmt.Println("------------ v.Edges.CpPointRewardMPH.Name:", v.Edges.CpPointRewardMPH.Name)
	Template.PointName = &v.Edges.CpPointRewardMPH.Name
}
相关推荐
heartbeat..1 小时前
Spring AOP 全面详解(通俗易懂 + 核心知识点 + 完整案例)
java·数据库·spring·aop
麦聪聊数据3 小时前
MySQL并发与锁:从“防止超卖”到排查“死锁”
数据库·sql·mysql
&岁月不待人&4 小时前
⏺ Android 录屏缩放异常排查:Pixel 3 XL 上的完美风暴
android
a3158238064 小时前
Android 大图显示策略优化显示(一)
android·算法·图片加载·大图片
tangweiguo030519874 小时前
从零开始:在 Windows 上使用命令行编译 Android .so 动态库(NDK + CMake + Ninja)
android
AC赳赳老秦4 小时前
DeepSeek 私有化部署避坑指南:敏感数据本地化处理与合规性检测详解
大数据·开发语言·数据库·人工智能·自动化·php·deepseek
阿波罗尼亚4 小时前
Tcp SSE Utils
android·java·tcp/ip
YMatrix 官方技术社区5 小时前
YMatrix 存储引擎解密:MARS3 存储引擎如何超越传统行存、列存实现“时序+分析“场景性能大幅提升?
开发语言·数据库·时序数据库·数据库架构·智慧工厂·存储引擎·ymatrix
辞砚技术录6 小时前
MySQL面试题——索引2nd
数据库·mysql·面试
linweidong6 小时前
C++thread pool(线程池)设计应关注哪些扩展性问题?
java·数据库·c++