有条件地构建查询并保持公共部分以不同方式执行

Build query conditionally and keeping the common part to execute differently

试图找出如何使用 gorm 有条件地构建查询,保存公共查询部分并执行它。

假设我正在查询如下所示的课程列表。

common_query_part := app.GetDB(). // <= this returns *gorm.DB
        Model(&models.Course{}).
        Where("status=?", models.CourseStatusPublished) //models.CourseStatusPublished is a constant

现在我想获取已发布课程的列表。并得到它的计数。所以我就这么试了。

published_course_count := *common_query_part

然后是课程列表

   result := common_query_part.
                 Offset(offset).
                 Limit(limit).
                 find(&courses)
   
       if result.Error !=nil {
         //handle error
       } 

和计数

result = published_course_count.Count(&total)
       
if result.Error !=nil {
             //handle error
           } 

第一部分完美运行。但是查询的第二部分不起作用,甚至不会产生任何错误。在这种情况下我该怎么办?公共查询部分可能庞大而复杂。因此,仅仅为了获取计数而再次重写它很容易出错。那么有没有一种方法可以让我保留公共查询部分并有时对已发布的课程执行它。有时对已发布的课程计数?

我不认为 GORM 打算让您以这种方式重复使用您的查询。很难确切地说,但它很可能不起作用,因为仍然有一些状态是共享的。

这:published_course_count := *common_query_partgorm.DB 结构的值进行复制,但是如果该结构包含任何指针(确实如此),那么这些指针也会被复制,从而导致两个带有指针的独立结构到相同的对象,因此仍然被“链接”。你需要一个专用的克隆功能,gorm中确实存在但没有暴露。

我建议您将公共部分的生成放在一个函数中并调用它两次,这样您就不必复制粘贴相同的查询。

func common_query_part() *gorm.DB {
    return app.GetDB().
        Model(&models.Course{}).
        Where("status=?", models.CourseStatusPublished)
}