如何插入 "one to one" 房间数据库
How to insert a "one to one" room database
我正在尝试在 android 中插入具有一对一关系的对象。
更准确地说,我正在尝试遵循以下示例
googles official documentation
我正在使用两个 classes 用户和库。
我遇到的问题是如何将元素插入数据库。
我的代码是这样写的
@Entity
data class Library(
@PrimaryKey(autoGenerate = true) val libraryId: Long = 0,
val userOwnerId: Long
)
@Entity
data class User(
@PrimaryKey(autoGenerate = true) val userId: Long =0,
val name: String,
val age: Int
)
data class UserAndLibrary(
@Embedded val user: User,
@Relation(
parentColumn = "userId",
entityColumn = "userOwnerId"
)
val library: Library
)
插入逻辑如下所示
private val repository = UserRepository(application)
fun insertUser() {
val user1 = User(name = "User1", age = 31)
val user2 = User(name = "User2", age = 32)
val library1 = Library(userOwnerId = user1.userId)
val library2 = Library(userOwnerId = user2.userId)
viewModelScope.launch {
repository.insertUser(user1)
repository.insertUser(user2)
repository.insertLibrary(library1)
repository.insertLibrary(library2)
}
存储库和 dao 的代码 class 如下所示
//repository
suspend fun insertUser(user: User) = appDataBase.userDao().insertUser(user)
suspend fun insertLibrary(library: Library)=appDataBase.userDao().insertLibrary(library)
//dao
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertUser(user: User)
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertLibrary(library: Library)
问题是库table中的外键总是0。
我认为您的问题是由于您插入库数据的方式所致。更具体地说,当您插入一个库时,您是否设置了该库的值 userOwnerId
? (我相信不会或正在将其设置为 0)。
考虑以下使用您的 类(用户、库和 userAndLibrary)的问题,其中包含以下 @Dao 和非常标准的 @Database :-
@Dao
abstract class AllDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun insert(library: Library): Long
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun insert(user: User): Long
@Query("SELECT * FROM user")
abstract fun getAllUsers(): List<User>
@Query("SELECT * FROM library")
abstract fun getAllLibraries(): List<Library>
@Query("SELECT * FROM user")
abstract fun getUsersAndThierLibrary(): List<UserAndLibrary>
}
- 注意插入 return Long(即插入行的 ID)
结合上面的代码在activity中(运行在主线程上为了方便和简洁):-
db = TheDatabase.getInstance(this)
dao = db.getAllDao()
/* Explanatory Insert */
var firstUser = User(name = "Susan",age = 20)
var firstUserId = dao.insert(firstUser)
dao.insert(Library(userOwnerId = firstUserId))
/* More Concise Inserts */
dao.insert(Library(userOwnerId = dao.insert(User(name ="Fred",age = 21))))
dao.insert(Library(userOwnerId = dao.insert(User(name ="Mary",age= 19))))
for (u: User in dao.getAllUsers()) {
Log.d(TAG," User is ${u.name} ID is ${u.userId} age is ${u.age}")
}
for (l: Library in dao.getAllLibraries()) {
Log.d(TAG,"Library is ${l.libraryId} owned by ${l.userOwnerId}")
}
for(ual: UserAndLibrary in dao.getUsersAndThierLibrary()) {
Log.d(TAG,"User = ${ual.user.name} Library ID is ${ual.library.libraryId}")
}
- 再次注意在插入用户时使用值returned(userId)。
可以看出,上面插入了 3 个用户和库。然后提取所有用户、所有库和 UserAndLibrary 的。结果是:-
2021-07-31 12:29:41.888 D/MYINFO: User is Susan ID is 1 age is 20
2021-07-31 12:29:41.889 D/MYINFO: User is Fred ID is 2 age is 21
2021-07-31 12:29:41.889 D/MYINFO: User is Mary ID is 3 age is 19
2021-07-31 12:29:41.890 D/MYINFO: Library is 1 owned by 1
2021-07-31 12:29:41.890 D/MYINFO: Library is 2 owned by 2
2021-07-31 12:29:41.890 D/MYINFO: Library is 3 owned by 3
2021-07-31 12:29:41.894 D/MYINFO: User = Susan Library ID is 1
2021-07-31 12:29:41.895 D/MYINFO: User = Fred Library ID is 2
2021-07-31 12:29:41.895 D/MYINFO: User = Mary Library ID is 3
- 即一切如预期。
这工作得很好,但我必须承认这对用户来说不是那么友好,并且在 google 的任何地方都没有记录。评论家是针对 google 而不是你。
是否可以这样做(c# 和 entity framework 示例)
var dept = new Department()
{
Name = "Admin"
};
var emp = new Employee()
{
Name = "Matt",
Designation = "Head",
Department = dept
};
using (var context = new CompanyContext())
{
context.Add(emp);
await context.SaveChangesAsync();
}
这将是使用框架库的一种非常直观的方式
我正在尝试在 android 中插入具有一对一关系的对象。 更准确地说,我正在尝试遵循以下示例 googles official documentation
我正在使用两个 classes 用户和库。 我遇到的问题是如何将元素插入数据库。 我的代码是这样写的
@Entity
data class Library(
@PrimaryKey(autoGenerate = true) val libraryId: Long = 0,
val userOwnerId: Long
)
@Entity
data class User(
@PrimaryKey(autoGenerate = true) val userId: Long =0,
val name: String,
val age: Int
)
data class UserAndLibrary(
@Embedded val user: User,
@Relation(
parentColumn = "userId",
entityColumn = "userOwnerId"
)
val library: Library
)
插入逻辑如下所示
private val repository = UserRepository(application)
fun insertUser() {
val user1 = User(name = "User1", age = 31)
val user2 = User(name = "User2", age = 32)
val library1 = Library(userOwnerId = user1.userId)
val library2 = Library(userOwnerId = user2.userId)
viewModelScope.launch {
repository.insertUser(user1)
repository.insertUser(user2)
repository.insertLibrary(library1)
repository.insertLibrary(library2)
}
存储库和 dao 的代码 class 如下所示
//repository
suspend fun insertUser(user: User) = appDataBase.userDao().insertUser(user)
suspend fun insertLibrary(library: Library)=appDataBase.userDao().insertLibrary(library)
//dao
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertUser(user: User)
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertLibrary(library: Library)
问题是库table中的外键总是0。
我认为您的问题是由于您插入库数据的方式所致。更具体地说,当您插入一个库时,您是否设置了该库的值 userOwnerId
? (我相信不会或正在将其设置为 0)。
考虑以下使用您的 类(用户、库和 userAndLibrary)的问题,其中包含以下 @Dao 和非常标准的 @Database :-
@Dao
abstract class AllDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun insert(library: Library): Long
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun insert(user: User): Long
@Query("SELECT * FROM user")
abstract fun getAllUsers(): List<User>
@Query("SELECT * FROM library")
abstract fun getAllLibraries(): List<Library>
@Query("SELECT * FROM user")
abstract fun getUsersAndThierLibrary(): List<UserAndLibrary>
}
- 注意插入 return Long(即插入行的 ID)
结合上面的代码在activity中(运行在主线程上为了方便和简洁):-
db = TheDatabase.getInstance(this)
dao = db.getAllDao()
/* Explanatory Insert */
var firstUser = User(name = "Susan",age = 20)
var firstUserId = dao.insert(firstUser)
dao.insert(Library(userOwnerId = firstUserId))
/* More Concise Inserts */
dao.insert(Library(userOwnerId = dao.insert(User(name ="Fred",age = 21))))
dao.insert(Library(userOwnerId = dao.insert(User(name ="Mary",age= 19))))
for (u: User in dao.getAllUsers()) {
Log.d(TAG," User is ${u.name} ID is ${u.userId} age is ${u.age}")
}
for (l: Library in dao.getAllLibraries()) {
Log.d(TAG,"Library is ${l.libraryId} owned by ${l.userOwnerId}")
}
for(ual: UserAndLibrary in dao.getUsersAndThierLibrary()) {
Log.d(TAG,"User = ${ual.user.name} Library ID is ${ual.library.libraryId}")
}
- 再次注意在插入用户时使用值returned(userId)。
可以看出,上面插入了 3 个用户和库。然后提取所有用户、所有库和 UserAndLibrary 的。结果是:-
2021-07-31 12:29:41.888 D/MYINFO: User is Susan ID is 1 age is 20
2021-07-31 12:29:41.889 D/MYINFO: User is Fred ID is 2 age is 21
2021-07-31 12:29:41.889 D/MYINFO: User is Mary ID is 3 age is 19
2021-07-31 12:29:41.890 D/MYINFO: Library is 1 owned by 1
2021-07-31 12:29:41.890 D/MYINFO: Library is 2 owned by 2
2021-07-31 12:29:41.890 D/MYINFO: Library is 3 owned by 3
2021-07-31 12:29:41.894 D/MYINFO: User = Susan Library ID is 1
2021-07-31 12:29:41.895 D/MYINFO: User = Fred Library ID is 2
2021-07-31 12:29:41.895 D/MYINFO: User = Mary Library ID is 3
- 即一切如预期。
这工作得很好,但我必须承认这对用户来说不是那么友好,并且在 google 的任何地方都没有记录。评论家是针对 google 而不是你。 是否可以这样做(c# 和 entity framework 示例)
var dept = new Department()
{
Name = "Admin"
};
var emp = new Employee()
{
Name = "Matt",
Designation = "Head",
Department = dept
};
using (var context = new CompanyContext())
{
context.Add(emp);
await context.SaveChangesAsync();
}
这将是使用框架库的一种非常直观的方式