英文:
How to populate and embedded array with gorm?
问题
我有两个包含以下数据的结构体:
type User struct {
Pics []Pic
}
type Pic struct {
Id int
UserId int64
}
尽管每次插入一个用户时,每个图片都会被插入到它们的表中,但是每次查找用户时,图片并没有被填充:
var users []User
db.Limit(pagesize).Where("updated_at > ?", date).Find(&users)
我做错了什么吗?
英文:
I have 2 structs with data like this:
type User struct {
Pics Pic[]
}
type Pic struct {
Id int
UserId int64
}
Although everytime I insert an User, Each of the pics are inserted on their table everytime I find the users, pics are not populated:
var users []User
db.Limit(pagesize).Where("updated_at > ?", date).Find(&users)
Am I doing something wrong?
答案1
得分: 3
你的模型(结构体)并不合理,因为User
有一个Pic
数组,表示一个用户对图片的一对多关系,然而你的用户本身没有id
属性,因此无法与Pic
表上的项目相关联。
用户应该有一个Id
属性,它将作为主键,UserId
是与之相关的Pic上的外键。如果这两个表/实体之间没有"关系",你将无法通过查询用户来返回图片。
我不确定你需要做什么才能使你的代码工作,因为示例是不完整的,但你首先需要一个Id
属性,你应该使用gorm注解将其指定为主键。你还应该在Pic结构体上使用注解,指明UserId是外键,Id是它的主键。
另外,只是提醒一下,你的数组并没有被嵌入。嵌入是一种语言特性,你没有使用它,如果你嵌入属性,它没有名称,可以直接从嵌入类型的实例中访问它的属性。
英文:
Your models (the structs) don't really make sense because User
have a Pic
array indicates a 'one to many' user to pics relationship however your user has no id property itself and there for cannot be related to items on the Pic
table.
User should have a property Id
which will be it's primary key and UserId
is a foreign key on Pic that relates to it. Without the 'relation' between these two tables/entities there's no way you're going to return pics by querying users.
I'm not sure what all you need to do to make your code work since the example is incomplete but the first thing you need is an Id
property which you should designate as a Primarykey with gorm annotations. You also should have annotations on the Pic struct saying UserId is a foreign key and Id is it's primary key.
Also, just fyi your array is not embedded. Embedding is a language feature which you're not using, if you embed the property it has no name and it's properties can be accessed directly from an instance of the embedding type.
答案2
得分: 1
我曾经遇到过这些问题。然后我使用了Join函数。看看我的示例,它完全正常工作:
type FileType struct {
Id int
}
type File struct {
Id int
FileType `xorm:"extends"`
}
file := File{Id: id}
has, err := eng.
Join("INNER", "FileType", "FileType.IdFileType = File.IdFileType").
Get(&file)
英文:
I had these issues once. Then I used Join function.
See my example that works just fine:
type FileType struct {
Id int
}
type File struct {
Id int
FileType `xorm:"extends"`
}
file := File{Id: id}
has, err := eng.
Join("INNER", "FileType", "FileType.IdFileType = File.IdFileType").
Get(&file)
答案3
得分: 0
你可能已经知道了。你需要像创建一个具有一对多关系的SQL表一样思考。这里有一个例子:
type Entry struct {
ID int
Name string
...
ContainerID int
}
type Container struct {
ID int
Tag int
Name string
...
Entries []Entry `gorm:"foreignkey:ContainerID"`
}
关键是如何填充它。我还没有找到一次性完成的方法。对于每个这样的依赖关系,你需要运行类似以下的代码:
c := getContainerFromDB(...)
if err := getROConn().Model(c).Related(&c.Entries, "Entries").Error; err != nil {
return errors.Wrap(err, "error getting container field")
}
希望对你有帮助!
英文:
You probably know by now. You got to think as if you are creating a SQL table with 1-to-many relationship. Here is an example:
type Entry struct {
ID int
Name string
...
ContainerID int
}
type Container struct {
ID int
Tag int
Name string
...
Entries []Entry `gorm:"foreignkey:ContainerID"`
}
The trick is to populate it. I am yet to find how to make it in one try. For every such dependency, you got to run something like:
c := getContainerFromDB(...)
if err := getROConn().Model(c).Related(&c.Entries, "Entries").Error; err != nil {
return errors.Wrap(err, "error getting container field")
}
答案4
得分: 0
尝试使用Preload
db.Limit(pagesize).Where("updated_at > ?", date).Preload("Pics").Find(&users)
英文:
Try Preload
db.Limit(pagesize).Where("updated_at > ?", date).Preload("Pics").Find(&users)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论