Sql server MsSql节点中的SequelizeJs关联

Sql server MsSql节点中的SequelizeJs关联,sql-server,node.js,express,sequelize.js,Sql Server,Node.js,Express,Sequelize.js,我在SQL Server中有预先存在的表,我想在NodeJs项目中使用这些表 第一个表是报表表,它有{ReportId,ReportName}列 第二个表是Favorites表,它有{FavoriteId,ReportId,UserName}列 您可以在下面找到模型定义。我想分配外键并建立依赖关系。最后,我想为特定用户选择带有收藏夹标志的报告 module.exports = function(sequelize, DataTypes) { var Favourite = sequeli

我在SQL Server中有预先存在的表,我想在NodeJs项目中使用这些表

第一个表是报表表,它有{ReportId,ReportName}列

第二个表是Favorites表,它有{FavoriteId,ReportId,UserName}列

您可以在下面找到模型定义。我想分配外键并建立依赖关系。最后,我想为特定用户选择带有收藏夹标志的报告

module.exports = function(sequelize, DataTypes) {
    var Favourite = sequelize.define("IUI_Favourites", {
            favourite_id: {
                type: DataTypes.INTEGER,
                primaryKey: true,
                field: 'iui_favourite_id' 
            },
            report_id: {
                type: DataTypes.INTEGER,
                field: 'iui_report_id' 
            },
            username: {
                type: DataTypes.STRING,
                field: 'iui_username'
            }
        },
        {
            timestamps: false,
            freezeTableName: true
        });
    return Favourite;
};


module.exports = function(sequelize, DataTypes) {
    var Report = sequelize.define("IUI_Reports", {
        report_id: {
            type: DataTypes.INTEGER,
            primaryKey: true,
            field: 'iui_report_id' 
        },
        report_name: {
            type: DataTypes.STRING,
            field: 'iui_report_name' 
        }
    },
    {
         timestamps: false,
         freezeTableName: true
    });
    return Report;
};
你能帮我吗?
提前感谢。

最喜爱的
模型中,您需要使用
关联
函数创建属性
classMethods

    // in Favourite model
    classMethods: {
        associate: function(models){
            this.belongsTo(models.Report, { foreignKey: 'iui_report_id' });
        }
    },
    timestamps: false,
    freezeTableName: true
});
这定义了模型
favorite
可以通过数据库中的
iui\u Report\u id
外键字段分配
Report

然后,在
报告
模型中,您必须定义1:M关系:

    // in Report model
    classMethods: {
        associate: function(models){
            this.hasMany(models.Favourite, { foreignKey: 'iui_report_id' });
        }
    },
    timestamps: false,
    freezeTableName: true
});
为了返回指定用户喜欢的报告,您必须使用指定的条件调用
Report
上的
findAll()
方法:

Report.findAll({
     include: [
         {
             model: Favourite,
             where: {
                 username: 'admin'
             }
         }
     ]
}).then((reports) => {
    // here you get reports that are favourited by user with username 'admin'
});
这将生成一个SQL查询,该查询将使用
reports.id=favorite.Report\u id
favorite.username='admin'
上的
JOIN
条件返回
Report
favorite.username='admin'
对象。我希望这就是你要找的

编辑

根据注释,如果任何用户都喜欢指定的报告,则需要将Favorite标志设置为
true
。为此,您必须将此标志字段添加到
报告
模型中,类似
的内容是受欢迎的。它可以是存储在数据库中的字段,也可以是具有自己的
getter
的sequelize字段(虚拟字段不存储在数据库中)

如果是虚拟场,它可能如下所示:

var Report=sequelize.define('Report'){
...
您是否喜欢:{
类型:DataTypes.VIRTUAL(DataTypes.BOOLEAN),
get:function(){
返回sequelize.models.favorite.count({
其中:{iui_report_id:this.get('report_id')}
})。然后((countResult)=>{
返回countResult>0;
});
}
}
}, {
//其他模型选项,例如classMethods等。
});
如果存在具有指定的
iui\u report\u id
值的
favorite
对象,则此虚拟属性将返回
true
。但是,它是异步的,因此需要使用
.then()
调用它,就像
report.get('is_favorited')。然后((result)=>{console.log(result);})

另一方面,如果要将该标志存储在数据库中,则在创建新的
收藏夹
模型实例时,必须手动将
is_favorited
字段值设置为true。为此,您可以使用
收藏夹
型号上的挂钩

//在收藏夹模型中
时间戳:false,
表名:true,
挂钩:{
afterCreate:函数(实例、选项){
返回sequelize.models.Report.findById(instance.get('iui\u Report\u id')。然后((Report)=>{
if(company&&!company.get('is_favorited')){
return company.set('is_favorited',true).save(),然后(()=>{return;});
}
}
}
//在报告模型中
var Report=sequelize.define('Report'{
...
您是否喜欢:{
类型:DataTypes.BOOLEAN,
defaultValue:false
}
}, {
//其他型号选项。。。
});
编辑2

根据您最后的评论,您希望创建如下查询

SELECT Reps.rep_id, Reps.rep_name, CASE WHEN Favs.rep_id IS NULL THEN FALSE ELSE TRUE END is_favourited
FROM Reps
LEFT OUTER JOIN (SELECT rep_id FROM Favs WHERE user = 'alex') Favs ON Reps.rep_id = Favs.rep_id
Report.findAll({
    include: [
        {
            model: Favourite,
            where: { username: 'alex' }, // or any other passed value
            attributes: []
        }
    ],
    attributes: ['report_id', 'report_name', sequelize.literal('CASE WHEN "IUI_Favourites"."report_id" IS NULL THEN FALSE ELSE TRUE END is_favourited')],
    raw: true // because your Report model does not have is_favourited field
}).then((rows) => {
    // result
});
此查询将始终返回
is_favorited=TRUE
,因为
JOIN
子句中的
ON
条件是
Reps.rep_id=Favs.repu id
,因此即使
Favs.rep_id
NULL
,那么
ON
条件也不会通过(因为
Reps.rep_id
是主键,不能为
NULL

但是,如果您真的想执行这样的查询,它将如下所示

SELECT Reps.rep_id, Reps.rep_name, CASE WHEN Favs.rep_id IS NULL THEN FALSE ELSE TRUE END is_favourited
FROM Reps
LEFT OUTER JOIN (SELECT rep_id FROM Favs WHERE user = 'alex') Favs ON Reps.rep_id = Favs.rep_id
Report.findAll({
    include: [
        {
            model: Favourite,
            where: { username: 'alex' }, // or any other passed value
            attributes: []
        }
    ],
    attributes: ['report_id', 'report_name', sequelize.literal('CASE WHEN "IUI_Favourites"."report_id" IS NULL THEN FALSE ELSE TRUE END is_favourited')],
    raw: true // because your Report model does not have is_favourited field
}).then((rows) => {
    // result
});

favorite
模型中,您需要使用
associate
函数创建属性
classMethods

    // in Favourite model
    classMethods: {
        associate: function(models){
            this.belongsTo(models.Report, { foreignKey: 'iui_report_id' });
        }
    },
    timestamps: false,
    freezeTableName: true
});
这定义了模型
favorite
可以通过数据库中的
iui\u Report\u id
外键字段分配
Report

然后,在
报告
模型中,您必须定义1:M关系:

    // in Report model
    classMethods: {
        associate: function(models){
            this.hasMany(models.Favourite, { foreignKey: 'iui_report_id' });
        }
    },
    timestamps: false,
    freezeTableName: true
});
为了返回指定用户喜欢的报告,您必须使用指定的条件调用
Report
上的
findAll()
方法:

Report.findAll({
     include: [
         {
             model: Favourite,
             where: {
                 username: 'admin'
             }
         }
     ]
}).then((reports) => {
    // here you get reports that are favourited by user with username 'admin'
});
这将生成一个SQL查询,它将使用
reports.id=favorite.Report\u id
favorite.username='admin'
上的
JOIN
条件返回
Report
favovorite
对象。我希望这就是您正在寻找的

编辑

根据评论,如果指定的报表受到任何用户的喜爱,您需要将Favorite flag设置为
true
。为此,您必须将此标志字段添加到
报表
模型中,类似于
是Favorited
。它可以是存储在数据库中的字段,也可以是自己的续集字段
getter
(虚拟字段不存储在数据库中)

如果是虚拟场,它可能如下所示:

var Report=sequelize.define('Report'){
...
您是否喜欢:{
类型:DataTypes.VIRTUAL(DataTypes.BOOLEAN),
get:function(){
返回sequelize.models.favorite.count({
其中:{iui_report_id:this.get('report_id')}
})。然后((countResult)=>{
返回countResult>0;
});
}
}
}, {
//其他模型选项,例如classMethods等。
});
此虚拟属性返回
true