3

我正在使用 Sequelize.js 在同一张表上进行双重连接。我有一组 Team 对象和一组 Game 对象。一个团队有很多游戏,所以它在游戏表中会有外键,但是每场游戏都有两个团队,所以我需要加入两次表。使用 sequelize ORM 执行此操作的最佳方法是什么。

Team = sequelize.define('teams',{
  name : Sequelize.STRING,
  location : Sequelize.STRING,
});

Game = sequelize.define('games',{
  homeTeamId : Sequelize.INTEGER,
  awayTeamId : Sequelize.INTEGER,
  location : Sequelize.STRING,
});

// Associations
Game.hasOne(Team, {foreignKey : 'homeTeamId'});
    .hasOne(Team, {foreignKey : 'awayTeamId'});

Team.hasMany(Game);

谢谢!

4

1 回答 1

4

这实际上是一个有趣的问题。目前 sequelize 不支持此功能,但绝对可行。我在下面概述了两种方法:

var Sequelize = require('./index');

var sequelize = new Sequelize('sequelize_test', 'root', null, {
  host: "127.0.0.1",
  port: 3306
});

var Team = sequelize.define('teams',{
  name : Sequelize.STRING,
  location : Sequelize.STRING
}, {
  instanceMethods: {
    getGamesOne: function () {
      var chainer = new Sequelize.Utils.QueryChainer();

      chainer.add(this.getHomeGames());
      chainer.add(this.getAwayGames());

      return new Sequelize.Utils.CustomEventEmitter(function (emitter) {
        chainer.run().done(function (err, results) {
          var home = results[0],
            away = results[1];

          if (err) emitter.emit('error', err)
          else emitter.emit('success', home.concat(away));
        });
      }).run();      
    },

    getGamesTwo: function () {
      return Game.findAll({ where: ["homeTeamId = ? OR awayTeamId = ?", this.id, this.id ]})
    }
  }
});

var Game = sequelize.define('games',{
  homeTeamId : Sequelize.INTEGER,
  awayTeamId : Sequelize.INTEGER,
  location : Sequelize.STRING
});

// Associations
Game.belongsTo(Team, {foreignKey : 'homeTeamId'})
    .belongsTo(Team, {foreignKey : 'awayTeamId'});

Team.hasMany(Game, { as: 'AwayGames', foreignKey : 'awayTeamId'});
Team.hasMany(Game, { as: 'HomeGames', foreignKey : 'homeTeamId'});

Team.find(1).done(function (err, team) {
  team.getGamesOne().done(function(err, games) {
    console.log(games);
  });
  team.getGamesTwo().done(function(err, games) {
    console.log(games);
  });
})

GetGamesOne 使用 sequelize 的关联来分别获取主场比赛和客场比赛,并在将它们返回给您之前加入。GetGamesTwo 手动构建查询,因此您只需与数据库对话一次。选择您喜欢的任何一个 - 其中一个可能不太清楚发生了什么,但您正在使用 sequelize 构建查询,因此即使您稍后更改键的名称,它仍然可以工作。二非常简短明了,但您必须自己处理查询。

我还将您从游戏到团队的关系更改为belongsTo- 意味着外键在游戏表中。

玩得开心使用 Sequelize ;-)

于 2013-01-29T17:05:05.267 回答