如何访问房间数据库中多对多关系的每一列 android

How to access each column on many-to-many relationships in room database android

所以这是数据库的图表

我想做的是加入所有这些 table 以获得每个 table 中的每一列,我在房间 example example1 example2 example3 中看到了多对多关系图示例但在这些示例中,关系 table (OrderItem) 只有 2 列,其中包含其他 tables(订单、项目)的 ID,它们忽略关系 table 上的值。但对我来说,我还想 access/get 关系 table (OrderItem) 上的列,即 quantitytotal_price

我试过这样的东西

物品模型

@Entity(tableName = "item_table")
data class ItemModel(

  @PrimaryKey
  @ColumnInfo(name = "id")
  val itemId: String,
  @ColumnInfo(name = "item_name")
  var itemName: String,
  @ColumnInfo(name = "item_price")
  var itemPrice: String,
  @ColumnInfo(name = "item_stock")
  var itemStock: Int
)

订单模型

@Entity(tableName = "order_table")
data class OrderModel(

  @PrimaryKey
  @ColumnInfo(name = "id")
  val orderId: String,
  @ColumnInfo(name = "order_total_price")
  val orderTotalPrice: String,
  @ColumnInfo(name = "order_pay")
  val orderPay: String,
  @ColumnInfo(name = "order_exchange")
  val orderExchange: String
)

OrderItemModel

@Entity(tableName = "order_item_table", primaryKeys = ["order_id", "item_id"])
data class OrderItemModel(

  @ColumnInfo(name = "order_id", index = true)
  var orderId: String,
  @ColumnInfo(name = "item_id", index = true)
  var itemId: String,
  @ColumnInfo(name = "quantity")
  val qty: Int,
  @ColumnInfo(name = "price")
  val price: String,
  @ColumnInfo(name = "total_price")
  val totalPrice: String
)

OrderWithItems

data class OrderWithItems(

  @Embedded
  val order: OrderModel,

  @Relation(
      entity = OrderItemModel::class,
      parentColumn = "id",
      entityColumn = "order_id"
  )
  val orderItems: List<OrderItemModel>,

  @Relation(
      entity = ItemModel::class,
      parentColumn = "id",
      entityColumn = "id",
      associateBy = Junction(
          OrderItemModel::class,
          parentColumn = "order_id",
          entityColumn = "item_id"
      )
  )
  val items: List<ItemModel>
)

但这给了我不一致的结果,有时索引 0(来自 ItemModel)上的 item_name 与索引 0(来自 OrderItemModel)上的数量匹配,有时不匹配。那么使用房间数据库访问每个 table 上每一列的正确方法是什么?

Then what is the correct way to access each column on every table using room database?

您需要遵循层次结构。

也就是说,在较低级别,您需要一个具有 @Embedded OrderItem 和 @Relation Item 的 OrderItemWithItem。然后你的 OrderWithItem 应该有 @Embedded 的订单和 @Relation 的 OrderItemWithItem.

But this give me inconcistence result

我相信您不想要通过关联引入的 many-many 关系。也就是说,一个订单将具有一组唯一的订单项,而不是具有许多订单项的订单,这些订单项也可能被其他订单使用。

所以我相信你想要这样的东西:-

data class OrderItemWithItem(
    @Embedded
    val orderItemModel: OrderItemModel,
    @Relation(entity = ItemModel::class, parentColumn = "item_id", entityColumn = "id")
    val itemList: List<ItemModel>
)
  • 较低的层次结构将包含一个项目列表(尽管您可能只需要 1 个)。

有:-

data class OrderWithItems(

    @Embedded
    val order: OrderModel,
    @Relation(entity = OrderItemModel::class, parentColumn = "id", entityColumn = "order_id")
    val orderWithItems: List<OrderItemWithItem>

)

工作Example/Demo

使用你的代码和上面的代码以及:-

@Dao
abstract class AllDao {

    @Insert
    abstract fun insert(orderModel: OrderModel): Long
    @Insert
    abstract fun insert(orderItemModel: OrderItemModel): Long
    @Insert
    abstract fun insert(itemModel: ItemModel): Long

    @Transaction
    @Query("SELECT * FROM order_table")
    abstract fun getAllFullOrders(): List<OrderWithItems>

}

然后使用 :-

    db = TheDatabase.getInstance(this)
    dao = db.getAllDao()

    val item1 = "Item1"
    val item2 = "Item2"
    val item3 = "Item3"

    val order1 = "Order1"
    val order2 = "Order2"
    val order3 = "Order3"

    dao.insert(ItemModel(item1,"Item1Name","10",100))
    dao.insert(ItemModel(item2,"Item2Name","20",200))
    dao.insert(ItemModel(item3,"Item3Name","30",300))

    dao.insert(OrderModel(order1,"0","?","?"))
    dao.insert(OrderModel(order2,"0","?","?"))
    dao.insert(OrderModel(order3,"0","?","?"))

    dao.insert(OrderItemModel(order1,item1,2,"100","200"))
    dao.insert(OrderItemModel(order2, item1,5,"100","500"))
    dao.insert(OrderItemModel(order2,item2,3,"200","600"))
    dao.insert(OrderItemModel(order3,item1,7,"100","700"))
    dao.insert(OrderItemModel(order3,item2,4,"200","800"))
    dao.insert(OrderItemModel(order3,item3,3,"300","900"))

    for(owi in dao.getAllFullOrders()) {
        Log.d("DBINFO","Order is ${owi.order.orderId} etc")
        for (oiwi in owi.orderWithItems) {
            Log.d("DBINFO","\t ItemId is ${oiwi.orderItemModel.itemId} Quantity is ${oiwi.orderItemModel.qty} Total is ${oiwi.orderItemModel.totalPrice}")
            for(i in oiwi.itemList) {
                Log.d("DBINFO","\t\tItem is ${i.itemName} name is ${i.itemName} price is ${i.itemPrice} in stock is ${i.itemStock}")
            }
        }
    }

日志中的结果包括:-

D/DBINFO: Order is Order1 etc
D/DBINFO:    ItemId is Item1 Quantity is 2 Total is 200
D/DBINFO:       Item is Item1Name name is Item1Name price is 10 in stock is 100

D/DBINFO: Order is Order2 etc
D/DBINFO:    ItemId is Item1 Quantity is 5 Total is 500
D/DBINFO:       Item is Item1Name name is Item1Name price is 10 in stock is 100
D/DBINFO:    ItemId is Item2 Quantity is 3 Total is 600
D/DBINFO:       Item is Item2Name name is Item2Name price is 20 in stock is 200

D/DBINFO: Order is Order3 etc
D/DBINFO:    ItemId is Item1 Quantity is 7 Total is 700
D/DBINFO:       Item is Item1Name name is Item1Name price is 10 in stock is 100
D/DBINFO:    ItemId is Item2 Quantity is 4 Total is 800
D/DBINFO:       Item is Item2Name name is Item2Name price is 20 in stock is 200
D/DBINFO:    ItemId is Item3 Quantity is 3 Total is 900
D/DBINFO:       Item is Item3Name name is Item3Name price is 30 in stock is 300