【问题标题】:Get the next ID before saving a record在保存记录之前获取下一个 ID
【发布时间】:2015-01-24 17:27:24
【问题描述】:

在保存数据对象之前获取下一个 ID 在技术上是否可行?新的 ID,直到现在还没有创建记录。

我想出的唯一解决方案是创建一个新表,每次创建类型为“x”的新数据对象时,我都会在其中保存最新的 ID,然后计数。

【问题讨论】:

    标签: silverstripe


    【解决方案1】:

    新的 ID,直到现在还没有创建记录。

    即使您确实获得了@schellmax 建议的“ID”,您也永远无法确定保存时可以使用相同的“ID”。这如果非常脆弱并且可以被打破,例如多个用户几乎同时尝试做同样的事情。

    这是我为需要在提交表单之前上传文件并将文件附加到记录的项目所做的。

    1. 无论是否提交,都先保存记录。现在,您拥有该记录的官方ID
    2. 在已有记录时附加任何文件/其他数据对象。
    3. 提交表单时,可选择以不破坏其他使用中记录的方式清理表格。

    这样,无论发生什么以及有多少用户同时尝试,您都拥有正确的ID。此外,除非您有成百上千的用户同时执行此操作,否则对性能的影响应该很小。


    示例(不确定它是否按原样工作,因为我将其剥离):

    public function QuoteForm() {
        $fields = new FieldList();
    
        // Clears out quotes older than 7 days
        Quote::removeEmptyQuotes();
    
        // Get the quote.
        $quote = $this->getQuote();
    
        $yourName = new TextField(
            'Name',
            _t('QuoteForm.YourName', 'Your name')
        );
        $yourName->setAttribute('required', true);
        $fields->push($yourName);
    
        $uploadField = new UploadField(
            'Files',
            _t('QuoteForm.Files', 'Select file*'),
            $quote->Files()
        );
        $uploadField->setRecord($quote);
        $uploadField->setFolderName('quotefiles');
        $uploadField->setConfig('canAttachExisting', false);
        $uploadField->getValidator()->setAllowedExtensions(array(
            'jpg', 'jpeg', 'png', 'gif', 'tiff',
            'odt', 'pdf', 'rtf', 'txt',
            'doc', 'docx',
            'ppt', 'pptx',
            'xls', 'xlsx'
        ));
        $uploadField->setAttribute('required', true);
        $fields->push($uploadField);
    
        $actions = new FieldList(
            new FormAction('saveQuoteRequest', _t('QuoteForm.Send', 'Send'))
        );
    
        return new Form($this, 'QuoteForm', $fields, $actions);
    }
    
    /*
     * Selects quote based on possible QuoteID from request.
     * If none are found / if the request param is empty,
     * creates a new Quote.
     *
     * @return Quote
     */
    protected function getQuote() {
        $quote = null;
        $quoteID = (int)Session::get('QuoteID');
        if ($quoteID > 0) {
            $quote = Quote::get()->byID($quoteID);
        }
        if ($quote === null) {
            $quote = new Quote();
            $quote->write();
        }
        Session::set('QuoteID', $quote->ID);
        return $quote;
    }
    

    【讨论】:

    • 如何保存开头的记录?让用户通过点击保存按钮来执行此操作还是自动执行此操作?
    • 自动调用$dataobject->write();。这样我们在给用户表单之前就有了ID。然后表单(可能还有会话)可以保留对 ID 的引用。
    • 您在何时何地打电话?
    • 首次创建数据对象时:$dataobject = new DataObject(); $dataobject->write();。您将手动检索 ID 的同一位置。
    • 但那会在 onBeforeWrite 中?对不起,但我不明白。 Dataobject 上没有初始化函数是吗?到目前为止,我无法弄清楚将其放置在哪里,以便用户在点击创建按钮后得到一个书面对象。可以发个例子吗?
    【解决方案2】:

    你可以先查询数据库:

    $nextId = MyDataobject::get()->sort('ID')->last()->ID + 1;
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多