Breeze在客户端设置多个外键

时间:2013-05-19 07:17:49

标签: javascript entity-framework breeze single-page-application

我有三个breeze实体,我的应用程序是一个很长的形式,它会在转到服务器进行保存之前一次向所有三个表添加记录。两个表驱动程序&车辆与AutoLead有关系,需要在客户端一次输入AutoLead表中的AutoLeadId。

所以我有一个表单,用户在AutoLead中输入信息,然后以一个无缝的形式将记录添加到Drivers and Vehicles表中。如何在不首先分离保存的情况下将ID分配给驱动程序和车辆,并首先保存AutoLead,返回新ID,然后再将其分配给驱动程序和车辆,然后再次保存。我想避免多次访问服务器只是为了生成车辆和驱动程序上导航属性的ID。

根据我的理解,breeze应该能够使用它创建的客户端的临时ID来修复这些ID。但是当我去做保存时,它不会改变这些ID。根据:http://www.breezejs.com/documentation/navigation-properties

如果我尝试直接使用对象设置导航属性,我会获得导航属性的未定义错误(请参阅下面的代码)。使用另一种方法,如果我尝试直接在他们的Id上设置外键我从SQL得到一个外键错误,因为它试图将-1推送到服务器(临时ID)。我知道我一定做错了。以下是我的一些代码:

创建新的客户端实体:

    // New entity creation functions
    var createAutoLead = function() {
        return manager.createEntity('AutoLead');
    };

    var createAutoLeadDriver = function () {
        return manager.createEntity('AutoLeadDriver');
    };

    var createAutoLeadVehicle = function () {
        return manager.createEntity('AutoLeadVehicle');
    };

    // Save Function Loop through all drivers and vehicles and set 
       their autoLeadId's before saving

    var saveAutoLead = function (newAutoLead, autoLeadDrivers, autoLeadVehicles) {

        // Loop through drivers and set the foreign keys
        for (var i = 0; i < autoLeadDrivers().length; i++) {
            autoLeadDrivers()[i].autoLead(newAutoLead);
        }

        // Loop through drivers and set the foreign keys
        for (var i2 = 0; i2 < autoLeadVehicles().length; i2++) {
            autoLeadVehicles()[i2].autoLead(newAutoLead);
        }

        manager.saveChanges()
            .then(saveSucceeded)
            .fail(saveFailed);

        function saveSucceeded() {
            return logger.log('Debug Message', 'Quote saved successfully', null, system.getModuleId(datacontext),
                    true, config.growlTypes.success);
        }

        return logger.log('Debug Message', 'Quote saved successfully', null, system.getModuleId(datacontext),true, config.growlTypes.success);
    };

2 个答案:

答案 0 :(得分:0)

能够弄清楚。对于有此问题的任何人,您必须直接设置导航属性,不要自己设置外键。修复是将导航属性作为一个函数推送,所以下面是修复代码。因为breeze实体被包含在一个可观察的实体中,所以我必须在最后将它作为函数添加到()。

   // Save auto lead
    var saveAutoLead = function (newAutoLead, autoLeadDrivers, autoLeadVehicles, newAutoLeadDriver, newAutoLeadVehicle) {

        // Detach orphan entities
        manager.detachEntity(newAutoLeadDriver());
        manager.detachEntity(newAutoLeadVehicle());

        // Loop through drivers and set the foreign keys
        for (var i = 0; i < autoLeadDrivers().length; i++) {
            autoLeadDrivers()[i]().autoLead(newAutoLead());
        }

        // Loop through drivers and set the foreign keys
        for (var i = 0; i < autoLeadVehicles().length; i++) {
            autoLeadVehicles()[i].autoLead(newAutoLead());
        }

        manager.saveChanges()
            .then(saveSucceeded)
            .fail(saveFailed);

        function saveSucceeded() {
            return logger.log('Debug Message', 'Quote saved successfully', null, system.getModuleId(datacontext),
                    true, config.growlTypes.success);
        }

        return logger.log('Debug Message', 'Quote saved successfully', null, system.getModuleId(datacontext),true, config.growlTypes.success);
    };

答案 1 :(得分:0)

我很高兴你弄清楚了。 我只想指出设置FK也会起作用。 在我使用Northwind的测试中:

var em = newEm();

// acting as Vehicle
var ord = em.createEntity("Order");
ord.setProperty("orderDate", new Date());

// acting as Driver
var emp2 = em.createEntity("Employee");
emp2.setProperty("firstName", "Test fn2");
emp2.setProperty("lastName", "Test ln2");
emp2.setProperty("fullName", "foo2");

// acting as AutoLead
var emp1 = em.createEntity("Employee");
emp1.setProperty("firstName", "Test fn1");
emp1.setProperty("lastName", "Test ln1");
emp1.setProperty("fullName", "foo1");

我可以将emp1与ord和emp2关联如下:

ord.employeeID(emp1.employeeID());
emp2.reportsToEmployeeID(emp1.employeeID());

ord.employee(emp1);
emp2.manager(emp1);

并且在两种情况下都会在保存后解析/更新FK。话虽这么说,我仍然建议您直接设置导航属性,而不是处理FK。