序列化:在findAll include中包括联接表属性

1 sql sql-server-2008 node.js sequelize.js

我目前正在使用NodeJS,MSSQL和Sequilize作为ORM来开发用于管理公司分支机构和员工的应用程序。

要求是跟踪某些更改,以便我们可以“追溯”过去的日期,并查看该特定时间点的公司状态。为此,我们使用时间戳记(initDateendDate)来跟踪我们关心的更改,即分支机构的更改以及活动分支机构中员工的流动。每次更改记录时,我们都将其设置为endDatenow()并使用和创建新记录endDate = null,因此,每个分支机构或分支雇员关系的“当前”版本都是endDate IS NULL

现在,Sequelize面临的问题是:在急于加载(即加入)分支机构endDate时,如何为分支机构-雇员关系指定?在下面的示例中,我要查询公司的“当前”状态,所以我要的是,但这实际上是一个参数,表示我们想要的时间点。findAll()includeendDate: null

非常感谢你的帮助。任何见解将不胜感激!

---这里包括模型定义和查询-

分支模型定义:

var BranchModel = db.define<BranchInstance, Branch>('Branch', {
    IdBranch: {
        primaryKey: true,
        type: DataTypes.INTEGER
    },
    Name: DataTypes.STRING,
    // ... other fields ...
    initDate: DataTypes.DATE,
    endDate: DataTypes.DATE
}, {
    timestamps: false,
    classMethods: {
        associate: function (models) {

            Branch.belongsToMany(models.model('Employee'), {
                through: {
                    model: models.model('Branch_Employee')
                },
                as: 'Employees',
                foreignKey: 'branchId'
            });

            // ... other associations ..

        }
    }
});
Run Code Online (Sandbox Code Playgroud)

员工模型定义:

var EmployeeModel = db.define<EmployeeInstance, Employee>('Employee', {
    idEmployee: {
        primaryKey: true,
        type: DataTypes.INTEGER
    },
    Name: DataTypes.STRING,
    // ... other fields ...
    active: DataTypes.BOOLEAN
}, {
    timestamps: false,
    defaultScope: {
        where: {
            active: true
        }
    },
    classMethods: {
        associate: function (models) {

            EmployeeModel.belongsToMany(models.model('Branch'), {
                through: {
                    model: models.model('Branch_Employee')
                },
                foreignKey: 'employeeId'
            });

            // ... other associations ...
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

联接表定义:

var Branch_Employee = db.define<BranchEmployeeInstance, BranchEmployee>('Branch_Employee', {
    branchId: DataTypes.INTEGER,
    employeeId: DataTypes.INTEGER
    // ... some other attributes of the relation ...
    initDate: DataTypes.DATE,
    endDate: DataTypes.DATE,
}, {
    timestamps: false,
    classMethods: {
        associate: function(models) {

            Branch_Employee.belongsTo(models.model('Employee'), {
                as: 'Employee',
                foreignKey: 'employeeId'
            });

            Branch_Employee.belongsTo(models.model('Branch'), {
                as: 'Branch',
                foreignKey: 'branchId'
            });
        }
    },
    instanceMethods: {
        // ... some instance methods ...
    }
});
Run Code Online (Sandbox Code Playgroud)

进行查询查询以获取每个在职员工,并希望加载与其相关的分支机构:

let employees = await EmployeeModel.findAll({
    logging: true,
    include: [{
        model: Branch,
        as: 'Branches',
        where: {
            endDate: null, // this would be [Branches].[endDate] IS NULL

            // i also need the generated query to include:
            // [Branches.Branch_Employee].[endDate] IS NULL

        },
        required: false
    }]
});
Run Code Online (Sandbox Code Playgroud)

上面查询生成的SQL看起来像这样:

SELECT [Employee].[idEmployee]
,[Employee].[Name]
,[Employee].[active]
,[Branches].[IdBranch] AS [Branches.IdBranch]
,[Branches].[Name] AS [Branches.Name]
,[Branches].[initDate] AS [Branches.initDate]
,[Branches].[endDate] AS [Branches.endDate]
,[Branches.Branch_Employee].[initDate] AS Branches.Branch_Employee.initDate]
,[Branches.Branch_Employee].[endDate] AS [Branches.Branch_Employee.endDate]
,[Branches.Branch_Employee].[branchId] AS Branches.Branch_Employee.branchId]
,[Branches.Branch_Employee].[employeeId] AS [Branches.Branch_Employee.employeeId]
FROM [Employee] AS [Employee]
LEFT OUTER JOIN (
    [Branch_Employee] AS [Branches.Branch_Employee]
    INNER JOIN [Branch] AS [Branches] 
    ON [Branches].[IdBranch] = [Branches.Branch_Employee].[branchId]
) ON [Employee].[idEmployee] = [Branches.Branch_Employee].[employeeId]
AND [Branches].[endDate] IS NULL
WHERE [Employee].[active] = 1;
Run Code Online (Sandbox Code Playgroud)

但是,实际上,我实际上需要进一步限制结果集,使其仅包括“当前”分支员工关系,例如:

[Branches.Branch_Employee].[endDate] IS NULL
Run Code Online (Sandbox Code Playgroud)

小智 6

我应该更多地归功于Sequelize文档,因为通常情况下,它都有答案。如果有人正在为这个特定问题而苦苦挣扎,我将其包括在内:

Sequelize doc中,该findAll(options)函数接受以下选项:

[options.include[].through.where] JoinToMany关系的联接模型上的对象筛选器。

这正是我所需要的!希望这可以帮助。