TClientDataSet, используемый как набор данных в памяти - можно ли применять обновления в памяти без сохранения данных в базе данных?

По умолчанию TClientDataSet отслеживает все изменения, сделанные в DataSet (вставки, обновления, удаления). Есть ли способ сообщить набору данных о принятии текущих изменений (скажем, после серии вставок с использованием вставки / публикации) без фактического вызова базы данных для сохранения чего-либо?

Одна из идей, которую я придумал, заключалась в том, чтобы использовать TDataSetProvider и реализовать событие BeforeUpdateRecord и установить для параметра Applied значение true. Мне в этом не нравятся две вещи. Мне нужно добавить еще два объекта (TDataSetProvider и объект TSQLQuery), и ApplyUpdates запускает транзакцию. Есть способ попроще?

Если я не установлю ProviderName в TClientDataSet, ApplyUpdates не удастся.

Спасибо


person costa    schedule 06.03.2014    source источник
comment
Установите для LogChanges значение false перед вставкой или вызовите MergeChangeLog. Или я не понял ..   -  person Sertac Akyuz    schedule 06.03.2014
comment
@SertacAkyuz: Вот и все. Пожалуйста, ответьте, чтобы я принял ваш ответ как решение.   -  person costa    schedule 06.03.2014
comment
@Sertac: Похоже, ты меня опередил. Если вы отправите ответ, содержащий эту информацию, я удалю свой. (Я видел вопрос и единственный ответ, но не читал комментарии ни к одному из них перед публикацией. Ответ по праву ваш.)   -  person Ken White    schedule 06.03.2014
comment
возможный дубликат Delphi - применение Delta к TClientDataSet   -  person Sir Rufo    schedule 06.03.2014
comment
@Ken - Готово. Спасибо за это, на самом деле вам не нужно следить за комментариями, прежде чем отвечать.   -  person Sertac Akyuz    schedule 06.03.2014


Ответы (3)


Вы можете установить для LogChanges значение false перед изменением набора данных. В качестве альтернативы, если вам нужен журнал изменений на любом этапе, вы можете вызвать MergeChangeLog < / a> для включения обновлений.

person Sertac Akyuz    schedule 06.03.2014

Имейте в виду, что есть ошибка (по крайней мере, все еще в D2006), которая может вызвать у вас большую головную боль: если LogChanges имеет значение False, некоторые функции фильтра работают неправильно: записи могут оставаться внутри отфильтрованного набора данных, даже если их значения не соответствуют заданным критериям фильтра.

См. Этот модульный тест:

  procedure TestCDS.TestLogChanges;
  var CDS: TClientDataset;
  begin
     CDS := TClientDataset.Create(NIL);
     try
        CDS.FieldDefs.Add('MyStringField', ftString, 20 );
        CDS.CreateDataSet;
        try
           CDS.LogChanges := False;
           CDS.Filter := 'MyStringField is null';
           CDS.Filtered := True;
           Check( CDS.RecordCount= 0);
           CDS.Insert;
           CDS.Post;
           Check( CDS.RecordCount= 1);
           CDS.Edit;
           CDS.FieldByName('MyStringField').AsString := 'Text';
           CDS.Post;
           Check( CDS.RecordCount= 0, 'Recordcount is not 0 after changing value!');
        finally
           CDS.Close;
        end;
     finally
        CDS.Free;
     end;
  end;

Также посмотрите здесь, очевидно, это более старая ошибка: http://www.delphigroups.info/2/f0/463155.html

person Udontknow    schedule 16.09.2015

Я так и использую. Я загружаю в него данные из базы данных, а затем отправляю данные в экземпляр FastReports, в формы PDF или электронную таблицу Excel. Это дает мне возможность использовать один процесс для создания различных видов вывода. Прошло некоторое время с тех пор, как я его настраивал, но я думаю, что настроил так, как вы описываете.

person jrodenhi    schedule 06.03.2014
comment
Прости. Я, наверное, упустил вашу точку зрения. Похоже, Сертак все равно дал вам то, что вам нужно. Надеюсь, он вернется и даст ответ. - person jrodenhi; 06.03.2014