簡體   English   中英

Sequelize BelongsToMany使用自定義連接表主鍵

[英]Sequelize BelongsToMany with custom join table primary key

我與中間的連接表有很多對多的關系。 表格為Cookoff,Participant和CookoffParticipant。 我應該提到我不允許Sequelize創建或修改我的表,我只是映射我現有的關系。 我需要幫助了解哪些關系選項告訴sequelize什么調用連接表與主表相關的外鍵。

據我了解,Sequelize假設CookoffID和ParticipantID是CookoffParticipant上的復合主鍵。 在我的情況下,我要求主鍵是一個標識列我正在調用CookoffParticipantID並在CookoffParticipant表中的CookoffID,ParticipantID對上創建一個唯一索引。

當我通過查詢cookoffParticipant表嘗試獲取cookoff和參與者數據時,Sequelize使用錯誤的鍵來完成連接。 我必須做一些簡單的事情。 下面是我的表結構和帶結果的查詢。

烹飪表

var Cookoff = sequelize.define("Cookoff", {

    // Table columns

    CookoffID: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    Title: {
        type: DataTypes.STRING,
        allowNull: false
    },
    EventDate: {
        type: DataTypes.DATE,
        allowNull: false
    }
}, _.extend({},

    // Table settings
    defaultTableSettings,

    {
        classMethods: {
            associate: function(models) {
                Cookoff.belongsToMany(models.Participant, {
                    through: {
                        model: models.CookoffParticipant
                    },
                    as: "Cookoffs",
                    foreignKey: "CookoffID",
                    otherKey: "ParticipantID"
                });
            }
        }
    }
));

參與者表

var Participant = sequelize.define("Participant", {

    // Table columns
    ParticipantID: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    Name: {
        type: DataTypes.STRING(100),
        allowNull: false
    }

}, _.extend({},

    defaultTableSettings,

    {
        classMethods: {
            associate: function(models) {
                Participant.belongsToMany(models.Cookoff, {
                    through: {
                        model: models.CookoffParticipant
                    },
                    as: "Participants",
                    foreignKey: "ParticipantID",
                    otherKey: "CookoffID"
                });
            }
        }
    }
));

Cookoff參與者表

var CookoffParticipant = sequelize.define("CookoffParticipant", {
    CookoffParticipantID: {
        type: DataTypes.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true
    },
    CookoffID: {
        type: DataTypes.INTEGER,
        allowNull: false,
        references: {
            model: cookoff,
            key: "CookoffID"
        }
    },
    ParticipantID: {
        type: DataTypes.INTEGER,
        allowNull: false,
        references: {
            model: participant,
            key: "ParticipantID"
        }
    }
}, _.extend(
    { },
    defaultTableSettings,
    {
        classMethods: {
          associate: function (models) {
              CookoffParticipant.hasOne(models.Cookoff, { foreignKey: "CookoffID" });
              CookoffParticipant.hasOne(models.Participant, { foreignKey: "ParticipantID" });

            }
        }
    }
));

我的查詢

return cookoffParticpants.findOne({
        where: { CookoffID: cookoffID, ParticipantID: participantID },
        include: [
            { model: participants },
            { model: cookoffs }
        ]
    });

生成的SQL

SELECT 
    [CookoffParticipant].[CookoffParticipantID], 
    [CookoffParticipant].[CookoffID], 
    [CookoffParticipant].[ParticipantID], 
    [Participant].[ParticipantID] AS [Participant.ParticipantID], 
    [Participant].[Name] AS [Participant.Name], 
    [Cookoff].[CookoffID] AS [Cookoff.CookoffID], 
    [Cookoff].[Title] AS [Cookoff.Title], 
    [Cookoff].[EventDate] AS [Cookoff.EventDate] 
FROM [CookoffParticipant] AS [CookoffParticipant] 
LEFT OUTER JOIN [Participant] AS [Participant] 
    ON [CookoffParticipant].[CookoffParticipantID] = [Participant].[ParticipantID]  -- This should be CookoffParticipant.ParticipantID
LEFT OUTER JOIN [Cookoff] AS [Cookoff] 
    ON [CookoffParticipant].[CookoffParticipantID] = [Cookoff].[CookoffID] -- This should be CookoffParticipant.CookoffID
WHERE [CookoffParticipant].[CookoffID] = 1 
AND [CookoffParticipant].[ParticipantID] = 6 
ORDER BY [CookoffParticipantID] 
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY;

你可以看到Sequelize試圖在Participant.ParticipantID上加入CookoffParticipant.CookoffParticipantID,它應該是CookoffParticipant.ParticipantID = Participant.ParticipantID,同樣適用於CookoffID。 我在這做錯了什么?

預先感謝您的幫助。

以下是您正在尋找的非常好的討論 他們非常好地總結了一下,你應該定義一個直通表,並在通過表中聲明belongsTo引用。 您的問題可能是您使用的是hasOne而不是belongsTo 此外,我認為你as鑰匙是倒退。

Cookoff.hasMany(Book, { through: CookoffParticipant })
Participant.hasMany(User, { through: CookoffParticipant })
CookoffParticipant.belongsTo(Cookoff)
CookoffParticipant.belongsTo(Participant)

這是我用來測試它的代碼。

Cookoff.js

module.exports = (sequelize, DataTypes) => {
    var Cookoff = sequelize.define("Cookoff", {
        CookoffID: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        }
    }, _.extend(
        {},
        {
            classMethods: {
                associate: function(models) {
                    Cookoff.belongsToMany(models.Participant, {
                        through: models.CookoffParticipant,
                        foreignKey: "CookoffID",
                        otherKey: "ParticipantID"
                    });
                }
            }
        }
    ));
    return Cookoff;
};

Participant.js

module.exports = (sequelize, DataTypes) => {
    var Participant = sequelize.define("Participant", {
        ParticipantID: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            autoIncrement: true
        }
    }, _.extend(
        {},
        {
            classMethods: {
                associate: function(models) {
                    Participant.belongsToMany(models.Cookoff, {
                        through: models.CookoffParticipant,
                        foreignKey: "ParticipantID",
                        otherKey: "CookoffID"
                    });
                }
            }
        }
    ));
    return Participant;
};

CookoffParticipant.js

module.exports = (sequelize, DataTypes) => {
    var CookoffParticipant = sequelize.define("CookoffParticipant", {
        CookoffParticipantID: {
            type: DataTypes.INTEGER,
            allowNull: false,
            primaryKey: true,
            autoIncrement: true
        }
    }, _.extend(
        {},
        {
            classMethods: {
                associate: function(models) {
                    CookoffParticipant.belongsTo(models.Cookoff, { foreignKey: "CookoffID" });
                    CookoffParticipant.belongsTo(models.Participant, { foreignKey: "ParticipantID" });
                }
            }
        }
    ));
    return CookoffParticipant;
};

test.js

const db = require('../db');
const Cookoff = db.Cookoff;
const Participant = db.Participant;
const CookoffParticipant = db.CookoffParticipant;
let cookoff,
    participant;

Promise.all([
    Cookoff.create({}),
    Participant.create({})
]).then(([ _cookoff, _participant ]) => {
    cookoff = _cookoff;
    participant = _participant;

    return cookoff.addParticipant(participant);
}).then(() => {
    return CookoffParticipant.findOne({
        where: { CookoffID: cookoff.CookoffID, ParticipantID: participant.ParticipantID },
        include: [ Cookoff, Participant ]
    });
}).then(cookoffParticipant => {
    console.log(cookoffParticipant.toJSON());
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM