在保存记录之前获取下一个 ID

Get the next ID before saving a record

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

我想出的唯一解决方案是创建一个新的 table,我将在其中保存最新的 ID,每次创建 'x' 类型的新数据对象时,我都会在其中保存最新的 ID,然后再进行计数.

您可以先查询数据库:

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

The ID of the new, until now not created record.

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

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

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

这样,无论发生什么情况以及有多少用户同时尝试,您都可以获得正确的 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;
}