我目前正在开发一个应用程序来管理公司的分支机构和员工,使用NodeJS,MSSQL和Sequilize作为ORM。
要求是以我们可以追溯的方式跟踪某些变化。到过去的日期,并查看该特定时间点的公司状况。为此,我们使用时间戳(initDate
和endDate
)来跟踪我们关注的更改,即对分支的更改以及活动分支中员工的移动。每次更改记录时,我们都会将其endDate
设置为now()
并创建一条新记录,其中包含更改endDate = null
,因此当前'每个分支或分支 - 员工关系的版本都是endDate IS NULL
。
我们现在面临的问题是Sequelize:我们如何在endDate
我们的员工时为分支员工关系指定findAll()
,同时急切加载(即{{1}他们的分支?在下面的示例中,我查询了当前的'公司的状态,所以我要求include
,但这实际上是一个说我们想要的时间点的论据。
非常感谢你的帮助。任何见解都会非常感激!
---这里我包括模型定义和查询---
分支模型定义:
endDate: 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 ..
}
}
});
加入表定义:
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 ...
}
}
});
Sequelize查询以获取每个活跃的员工,渴望加载与他们相关的分支:
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 ...
}
});
上述查询生成的SQL如下所示:
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
}]
});
但是,我实际上需要进一步限制结果集,只包括“当前&#39;分支 - 员工关系,即:
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;
答案 0 :(得分:6)
我应该更多地归功于Sequelize文档,因为通常情况下,它有答案。我包括它以防其他人正在努力解决这个特殊问题:
从Sequelize doc,findAll(options)
函数接受以下选项:
[options.include[].through.where]
对象过滤了关于belongsToMany关系的连接模型。
这正是我所需要的!希望这会有所帮助。