如何为该交易添加多个产品?
您可以使用映射/关联/关系(和其他名称)表(实体)来反映多对多关系(即,许多交易可以用于(相关)单个产品,并且许多产品可以由单笔交易)。
这是一个主要包含 2 列的表,其中一列用于与一个部分(交易)相关(唯一标识)的值,另一列用于与另一部分(产品)相关的值。
所以说 交易 1 有 产品 2,3,4,5 & 6 和 交易 2 具有 产品 1,3,5,7,9
映射表将包含:-
1 2
1 3
1 4
1 5
1 6
2 1
2 3
2 9
2 7
2 5
我是否需要获取该特定交易的 id,
之前将其设置为我的 Product 对象中的相应 txn_id
插入它,或者 Room 会自动正确插入东西,如果
您已将 Product 实体设置为具有引用
事务类?
关于 SQLite 外键(Room or not),它只是定义了一个约束(规则),即子列值中的值必须是父列中的值。
没有执行任何魔法来确定值(如果您仔细想想,它怎么知道什么与什么相关)。您必须在插入时以编程方式确定值。
所以答案是你需要对 id 的
进行评分
映射和外键使用示例
也许考虑以下几点:-
DROP TABLE IF EXISTS Map1;
DROP TABLE IF EXISTS Map2;
DROP TABLE IF EXISTS Transactions;
DROP TABLE IF EXISTS Products;
CREATE TABLE IF NOT EXISTS Transactions (id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE IF NOT EXISTS Products (id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO Transactions (name) VALUES('Take'),('Give'),('Buy'),('Sell');
INSERT INTO Products(name) VALUES('Tea'),('Coffee'),('Water'),('Beer');
/* Mapping table without foreign keys */
CREATE TABLE IF NOT EXISTS Map1 (
txn_id INTEGER,
prd_id INTEGER,
UNIQUE(txn_id,prd_id) /* <- prevents duplication */
);
/* Mapping Table with foreign keys and cascading deletes and updates */
CREATE TABLE IF NOT EXISTS Map2 (
txn_id INTEGER
REFERENCES Transactions(id)
ON DELETE CASCADE /* if parent is deleted then all children that map to that parent are deleted (only the maps rows) */
ON UPDATE CASCADE, /* like wise for updates (only if the id is updated) */
prd_id INTEGER
REFERENCES Products(id)
ON DELETE CASCADE
ON UPDATE CASCADE,
UNIQUE(txn_id,prd_id)
);
INSERT INTO Map1 VALUES(1,1),(1,4),(2,3),(2,2),(3,1),(3,2),(3,3),(3,4),(4,2);
INSERT INTO Map2 VALUES(1,1),(1,4),(2,3),(2,2),(3,1),(3,2),(3,3),(3,4),(4,2);
/*Result 1 Mapped via Map1 table without foreign keys */
SELECT Transactions.name AS TransactionName, Products.name AS ProductName,
'Transaction '||txn_id||' maps to Product '||prd_id AS mapping
FROM Transactions
JOIN Map1 ON Transactions.id = Map1.txn_id
JOIN Products ON Map1.prd_id = Products.id
;
/* Result 2 Mapped via Map2 table that has Foreign keys (no difference) to Result1 */
SELECT Transactions.name AS TransactionName, Products.name AS ProductName,
'Transaction '||txn_id||' maps to Product '||prd_id AS mapping
FROM Transactions
JOIN Map2 ON Transactions.id = Map2.txn_id
JOIN Products ON Map2.prd_id = Products.id
;
/* Add a rouge mapping entry to Map1 */
INSERT INTO Map1 VALUES (5,6); /* oooops niether transaction or Product exists */
/* Result 3 no issues with useless rouge entry */
SELECT Transactions.name AS TransactionName, Products.name AS ProductName,
'Transaction '||txn_id||' maps to Product '||prd_id AS mapping
FROM Transactions
JOIN Map1 ON Transactions.id = Map1.txn_id
JOIN Products ON Map1.prd_id = Products.id
;
/* Try adding rouge entry to Map 2. Does not work */
INSERT INTO Map2 VALUES (5,6); /* oooops niether transaction or Product exists */
;
代码:-
- 如果存在则删除现有表(请注意由于 FK 的顺序)
- 创建交易和产品表。
- 向 Transactions 和 products 表添加一些数据。
- 不使用外键创建 Map1 映射表。
- 使用外键创建 Map2 映射表。
- 加载具有相同数据的映射表。
- 根据/使用映射表 Map1 提取数据,生成结果 1。
- 根据/使用映射表 Map2 提取数据,生成结果 2。
- 插入 rouge 行 t0 Map1,尝试将 id 为 5 的不存在 Transaction 映射到 id 为 6 的不存在 Product
- 像以前一样从 Map1 中提取数据
- 向 Map2 插入 rouge 行,由于外键约束而失败。
结果
带有消息:-
INSERT INTO Map2 VALUES (5,6)
> FOREIGN KEY constraint failed
> Time: 0s