Sequelize.js 无法使虚拟字段在Sequelize中工作

Sequelize.js 无法使虚拟字段在Sequelize中工作,sequelize.js,Sequelize.js,我用尽了在这里和其他地方能找到的一切。看起来其他人正在取得成功,但我所做的一切都不允许我看到任何虚拟字段。我尝试了两种方法,一种是作为领域,另一种是作为获取方法,但都无济于事。我已经确保在我的项目中安装了最新的Sequelize版本 以下是对象定义: var Orderitem = sequelize.define("Orderitem", { description: { type: DataTypes.STRING(80), allowNull: false }, quant

我用尽了在这里和其他地方能找到的一切。看起来其他人正在取得成功,但我所做的一切都不允许我看到任何虚拟字段。我尝试了两种方法,一种是作为领域,另一种是作为获取方法,但都无济于事。我已经确保在我的项目中安装了最新的Sequelize版本

以下是对象定义:

var Orderitem = sequelize.define("Orderitem", {
    description: { type: DataTypes.STRING(80), allowNull: false },
    quantity: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0},
    unitWeight: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0},
    price: { type: DataTypes.DECIMAL(9,2), allowNull: false, defaultValue: 0},

    totalPrice: { 
      type: DataTypes.VIRTUAL(DataTypes.DECIMAL(9,2), ['price', 'quantity']),
      get() {
        //return this.getDataValue('unitWeight') * this.getDataValue('quantity');
        return 195.99;
      }
    }, 
    totalWeight: { 
      type:  DataTypes.VIRTUAL(DataTypes.DECIMAL(9,2), ['unitWeight', 'quantity']),
      get() {
        //return this.getDataValue('unitWeight') * this.getDataValue('quantity');
        return 45;
      }
    },
  }, {
/*
    getterMethods: {
      testFoo: function () {
          return 'Foo';
      },
      totalPrice: function () { 
        return  this.getDataValue('price') * this.getDataValue('quantity');
      },
      totalWeight: function() {
        return this.getDataValue('unitWeight') * this.getDataValue('quantity');
      }
    },
*/
    classMethods: {
      associate: function(models) {
        Orderitem.belongsTo(models.Order, {onDelete: 'CASCADE'})
    }
}
如前所述,它正在尝试使用虚拟类型的属性定义。我也尝试过只使用虚拟的,没有其他类型或依赖项。为了进行测试,我还硬编码了样本返回值

使用getterMethods的替代方法(在这里注释)也没有更好的效果

根据我能找到的所有内容,我应该能够执行查找(findOne、findAll等),这些内容应该与所有其他内容一起作为字段返回。前4个字段从数据库返回预期值。虚拟字段找不到。使用上述任何一种方法,我做错了什么

检索代码为:

OrderController.items = function (orderId, callback) {
    models.Orderitem.findAll({
        //attributes: Object.keys(models.Orderitem.attributes).concat([ 'totalPrice','totalWeight']),
        where: {orderId: orderId}, raw: true
    }).then(function(orderitems) {
        callback(null, orderitems)
    }).catch(function(error) {
        callback(error, null)
    });
 };

没有错误,项目按预期检索,除虚拟字段外,一切都正常工作。它们根本就不存在。请求原始对象或完整对象没有任何区别。

虚拟对象按照其定义的方式工作

问题在于检索结果的方式。通过在查询中使用
raw
选项,Sequelize假定您不想创建DAO,因此它不会评估虚拟对象,也不会创建实例本身

OrderController.items = function (orderId, callback) {
    models.Orderitem.findAll({    
        where: {orderId: orderId} // commenting out `raw: true`
    }).then(function(orderitems) {   
        if ( orderitems.length > 0 ) { 
            console.log(orderitems[0].totalPrice);
        };
        callback(null, orderitems)
    }).catch(function(error) {
        callback(error, null)
    });
 };

您可以在。

中阅读有关
raw
选项的更多信息。虚拟机按照其定义的方式工作

问题在于检索结果的方式。通过在查询中使用
raw
选项,Sequelize假定您不想创建DAO,因此它不会评估虚拟对象,也不会创建实例本身

OrderController.items = function (orderId, callback) {
    models.Orderitem.findAll({    
        where: {orderId: orderId} // commenting out `raw: true`
    }).then(function(orderitems) {   
        if ( orderitems.length > 0 ) { 
            console.log(orderitems[0].totalPrice);
        };
        callback(null, orderitems)
    }).catch(function(error) {
        callback(error, null)
    });
 };

您可以在中阅读有关
raw
选项的更多信息。

执行查找操作(findOne、findAll等)后,您必须显式访问这些
虚拟字段

仔细查看
console.log('orderitem:',orderitem)
不打印
totalPrice
,但
totalPrice
位于此处,返回在
console.log('totalPrice(虚拟字段):',orderitem.totalPrice)
中看到的值


您必须访问该值,当您访问该值时,Javascript会在运行时生成值。

执行查找操作(findOne、findAll等)后,您必须显式访问这些
虚拟字段

仔细查看
console.log('orderitem:',orderitem)
不打印
totalPrice
,但
totalPrice
位于此处,返回在
console.log('totalPrice(虚拟字段):',orderitem.totalPrice)
中看到的值


这是一个你必须访问的值,当你访问它时,Javascript会在运行时生成值。

对我来说似乎很有效,你能粘贴你的检索代码吗?在原始帖子中添加了检索代码-似乎无法在注释中很好地格式化它。挖掘整个返回的对象(关闭raw)我在:orderlines[0]中找到了对我的虚拟字段的引用。_proto__;在这种情况下,attributes属性是一个包含我的虚拟字段的名称数组,每个属性都有一个字段-除了我的虚拟字段的值分别为-199.95和45之外,所有属性都未定义。如果raw设置为true,则无法完成此操作。测试更多我还看到,如果将这些字段设置为其他两个字段的乘积,它们将保持未定义状态,因为您的实例的数据不应该以这种方式访问。您可以安全地执行
orderitems[0].toJSON()
,这将带来与原始结果相同的结果,但这一次包含虚拟结果:)似乎对我有效,您是否也可以粘贴您的检索代码?将检索代码添加到原始帖子中-似乎无法在注释中很好地格式化它。挖掘整个返回的对象(禁用raw)我在以下位置找到对虚拟字段的引用:orderlines[0]._proto__;在这种情况下,attributes属性是一个名称数组,其中包括我的虚拟字段,每个属性都有一个字段-所有属性都未定义,除了我的虚拟字段的值(分别为-199.95和45)之外。如果原始设置为true,则无法实现。通过测试,我还看到这些如果将其设置为其他两个字段的乘积,则将保持未定义状态。这是因为您的实例的数据不应以这种方式访问。您可以安全地执行
orderitems[0]。toJSON()
,这将产生与原始结果相同的结果,但这次包含虚拟结果:)谢谢您的帮助。原始选项的文档没有说明不允许虚拟字段工作,因此我不确定人们应该如何知道这一点。因此,为了获得虚拟属性,我不能使用raw,我必须转换为JSON??似乎两者都有可能损害性能,尤其是不能使用raw。性能将受到影响。是的,你说得对。然后,您根本不能使用virtuals,只需设法用您想要的值丰富您的
raw
对象。<代码> RAW 选项不会实例化您的结果,因此它不仅考虑虚拟,而且不考虑类型等。您将基本绕过ORM内的所有逻辑,这是快的-是的,但是为什么您首先需要ORM。首先:它现在正在工作。非常感谢。应用程序在服务器端呈现,对象不会发送到客户端或在客户端进行操作。因此,不需要一个完整的对象。在服务器端,raw实际上不是问题,因此需要它来获取虚拟表和其他好东西实际上不是问题。但是,必须转换为JSON,然后将其解析回对象,以便