powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Копирование данных из датасета в поля класса/записи
23 сообщений из 23, страница 1 из 1
Копирование данных из датасета в поля класса/записи
    #39887921
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем добрый день. Написал код копирования данных из любого датасета в поля любых записей или классов. Возможно кому-то будет интересно. В плане возможных доработок, можно было бы обобщить для работы со свойствами и попробовать избавится от var при передаче параметров.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
unit MakhDBCommon;
//(c) 2019 Makhaon Software

interface

uses
Data.DB,
System.Classes,
System.SysUtils,
System.Rtti;

type
DBFieldAttribute = class(TCustomAttribute)
strict private
FFormatParam: string;
FFieldName: string;
public
constructor Create; overload;
constructor Create(const AFieldName: string); overload;
constructor Create(const AFieldName, AFormatParam: string); overload;
property FieldName: string Read FFieldName;
property FormatParam: string Read FFormatParam;
end;

type
TDSHelper<T> = class
class procedure DataSetToVar(DataSet: TDataSet; var Variable: T; ClearRec: boolean = True);
class function DataSetToRecords(DataSet: TDataSet; OnFoundRec: TNotifyEvent = nil): TArray<T>;
end;

implementation

class procedure TDSHelper<T>.DataSetToVar(DataSet: TDataSet; var Variable: T; ClearRec: boolean = True);
var
Context: TRttiContext;
Fields: TRttiType;
Field: TRttiField;
Attr: TCustomAttribute;
AttrAs: DBFieldAttribute;
DBField: TField;
begin
if ClearRec then
Variable := Default(T);
Context := TRttiContext.Create;
try
Fields := Context.GetType(TypeInfo(T));
for Field in Fields.GetFields do
for Attr in Field.GetAttributes do
if Attr is DBFieldAttribute then
begin
AttrAs := DBFieldAttribute(Attr);
DBField := DataSet.FindField(AttrAs.FieldName);
if Assigned(DBField) then
if (Field.FieldType is TRttiStringType) then
if AttrAs.FormatParam.IsEmpty then
Field.SetValue(@Variable, TValue.From(DBField.AsString.TrimRight))
else
Field.SetValue(@Variable, TValue.From(Format(AttrAs.FormatParam, [DBField.AsString.TrimRight])))
else if Field.FieldType.Handle = TypeInfo(boolean) then
Field.SetValue(@Variable, TValue.From(DBField.AsString.StartsWith('+')))
else
Field.SetValue(@Variable, TValue.From(DBField.AsVariant));
end;
finally
Context.Free;
end;
end;

class function TDSHelper<T>.DataSetToRecords(DataSet: TDataSet; OnFoundRec: TNotifyEvent = nil): TArray<T>;
var
i: integer;
begin
with Dataset do
begin
First;
SetLength(Result, RecordCount);
i := 0;
while not Eof do
begin
TDSHelper<T>.DataSetToVar(Dataset, Result[i]);
if Assigned(OnFoundRec) then
OnFoundRec(DataSet);
Inc(i);
Next;
end;
end;
end;

{ DBFieldAttribute }

constructor DBFieldAttribute.Create;
begin
inherited Create;
FFieldName := '';
end;

constructor DBFieldAttribute.Create(const AFieldName: string);
begin
inherited Create;
FFieldName := AFieldName;
FFormatParam := '';
end;

constructor DBFieldAttribute.Create(const AFieldName, AFormatParam: string);
begin
inherited Create;
FFieldName := AFieldName;
FFormatParam := AFormatParam;
end;

end. 

...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39887928
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Использование:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
type
 TNodeParams = record
  UID:         string;
  [DBField('AE_TITLE')]
  AETitle:     string;
  [DBField('HOSTNAME')]
  HostName:    string;
  Port:        string;
  Description: string;
  IsLite:      string;
  [DBField('IS_MOST_PRIOR')]
  IsMostPrior: string;
  [DBField('ADD_HOSTNAMES')]
  AddIPs:      string;
 end;

FDataset1.FetchAll;
TDSHelper<TNodeParams>.DataSetToRecord(FDataset1, NodeParams);
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39887934
AlexeyM123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в догонку
DataSet Enumerator от Uwe Raabe
https://www.uweraabe.de/Blog/?s=Dataset Enumerator
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39887981
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня на XE6 не взлетел, увы. Синтаксиса не хватает. Пришлось свой делать.
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39887997
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon
У меня на XE6 не взлетел, увы. Синтаксиса не хватает. Пришлось свой делать.

У меня D7 и вся ваша примочка не взлетела
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39888019
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBr,

"В Delphi 2010 появились пользовательские атрибуты, которые можно добавить к объявлениям типов и методам"

D2010 минимум. Меньше, увы, никак.
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39888023
AlexeyM123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я к сожалению не могу найти ссылку, но Uwe Raabe писал,
что вся его конструкция работает на >= XE8 только
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39888133
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как минимум, я бы один раз сделал сопоставление поля датасета <=> поля записи, а потом бы уже в цикле вызывал
makhaon
Код: pascal
1.
TDSHelper<T>.DataSetToVar(Dataset, Result[i]);

ну и вот это
makhaon
Код: pascal
1.
SetLength(Result, RecordCount);

работать не будет. Нужно записи складывать в TList<T>, а потом делать
Код: pascal
1.
Result := List.ToArray;



Далее, код будет работать только для Record. Для объектов классов будет AV

Ну и остальное по мелочи
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39888273
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

авторSetLength(Result, RecordCount);

Это работает точно. Ну а вообще правки принимаются.
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39888297
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon
Это работает точно.
Значит (не) повезло с датасетом. Попробуй на IBX
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39888303
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

IBX/UniDAC, пока все ок. А что с IBX'ом не так? Записи если отфетчить, как я в примере написал, то будет ок. Но видимо надежнее в классее Last сделать.
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39888752
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon
Записи если отфетчить, как я в примере написал, то будет ок
Так это же читерство.
makhaon
надежнее в классее Last сделать.
И нарваться на Unidirectional.

Надежнее вот так
_Vasilisk_
Нужно записи складывать в TList<T>, а потом делать
Код: pascal
1.
Result := List.ToArray;

...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39888758
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вся эта возня с ORM-ом на коленке действительно способна сэкономить время при разработки
приложения? Отсюда всё выглядит так, что проще написать десяток присваиваний, чем вот так
вот прыгать с бубном.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39888759
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
дык тут важен сам процесс.
приседания ради приседаний.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39888794
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут как обычно дело хозяйское :) Хотите юзайте, хотите дописывайте, не хотите - пишите по-старинке.
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39889101
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
Вся эта возня с ORM-ом на коленке действительно способна сэкономить время при разработки
приложения? Отсюда всё выглядит так, что проще написать десяток присваиваний, чем вот так
вот прыгать с бубном.
Я писал подобную систему для конвертации из/в JSON. Теперь у меня сериализация/десериализация любого объекта/рекорда выполняется одной строкой. Ну и плюс определение атрибутов. Но у меня кода побольше будет. Сильно побольше.
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39889282
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Это отдельная проблема совсем. я с помощью SuperObject решаю. Есть там, правда, одина неприятная проблема (утечки), пришлось костыль дописывать, концов быстро не нашел.
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39889284
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon
я с помощью SuperObject решаю
У меня на стандартном System.JSON и атрибутах. Плюс возможность задать кастомную сермализацию/десериализацию для отдельных полей. Ну и поддержка Default значений
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39889319
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

стандартная мне не подходит из-за непереносимости delphi <> lazarus. у нас проекты в двух средах собираются.
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39889325
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon,

если не секрет - а для каких ОС, которын не поддерживает делфи, собирается ваш проект на лазарусе?
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39889419
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2,

для линукса. проекты начинались тогда, когда поддержки еще не было. ну а сейчас уже нет смысла на делфи тянуть все, под лазарем работает нормально. пока три проекта по 300-700 тысяч строк.
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39889937
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaon
asutp2,

для линукса. проекты начинались тогда, когда поддержки еще не было. ну а сейчас уже нет смысла на делфи тянуть все, под лазарем работает нормально. пока три проекта по 300-700 тысяч строк.


Под все версии линукса? Или под конкретную сборку конкретного заказчика? Аппаратная платформа x86_64? Интересно, что сейчас используется в России в бизнесе кроме x86 :)
...
Рейтинг: 0 / 0
Копирование данных из датасета в поля класса/записи
    #39889947
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
makhaon
asutp2,

для линукса. проекты начинались тогда, когда поддержки еще не было. ну а сейчас уже нет смысла на делфи тянуть все, под лазарем работает нормально. пока три проекта по 300-700 тысяч строк.


Под все версии линукса? Или под конкретную сборку конкретного заказчика? Аппаратная платформа x86_64? Интересно, что сейчас используется в России в бизнесе кроме x86 :)


Под все :) Пока что везде удалось установить и запустить, где пробовали и нужно было - уже с десяток веток наверно. И гуевых и консольных, всяко бывает. У нас, увы, выбора нет - должно работать везде, где нужно. Разработка под Убунтой. Аппаратная 86х64, насчет других аппаратных платформ не знаю.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Копирование данных из датасета в поля класса/записи
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]