Datasnap i Tclientdataset

0

Stanąłem przed takim problemem, muszę przenieść aplikację z modelu dwuwarstwowego, klient->sql_serwer_bazy_danych , do modelu trójwarstwowego , klient->serwer_aplikacji->sql_serwer_bazy_danych .
użwywam Delphi 2010 Enterprise, więc postanowiłem użyć technologii Datasnap, i pierwsze próbne zadanie jakie sobie postawiłem to utworzenie po stronie klienta dwupolowej tabeli, z polami "ilosc" i "cena" , następnie przesłanie tej tabeli do serwera aplikacji, który ma zwrócić całkowitą wartość tableli i zsumować dla całej tabeli iloczyn pól "ilosc"
"cena" , czyli umownie (sum(ilosc*cena)).
W tym celu po stronie klienta tworzę tabelę klasy TClientDataset , z polami "ilosc" i "cena" , wypełniam ją konkretnymi wartościami i przesyłam do serwera przy pomocy metody "proxy.pobierz_sprzedaz(ClientDataSet1)"
Serwer prawidłowo oblicza i zwraca całkowitą wartość tabeli.
Problem pojawia się , kiedy chcę usunąc z pamięci stworzoną tabelę "ClientDataSet1" (metodą "free") , bo wtedy pojawia się wyjątek "invalid pointer operation"
To wyglada tak, jakby wywołanie metody "proxy.pobierz_sprzedaz(ClientDataSet1)" w jakis sposób modyfikowało samą tabelę "clientdataset1" w taki sposób , ze nie można w prosty sposób, czyli metodą "free", zwolnic obiektu,
sprawdzenie czy jest "clientdataset1.active" również genereuje taki sam wyjątek.
Opisany objawy w żadnym stopniu nie zależą o tego co się dzieje po stronie serwera, bo w skrajnym testowym przypadku serwer zupełnie nic nie robił z otrzymanym datasetem , zupełnie go pomijał i od razu zwracał stałą wartośc równą "0"

poniżej kod programu

unit main;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, WideStrings, DbxDatasnap, DB, SqlExpr, DBClient, StdCtrls;

type
TForm1 = class(TForm)
DATASNAPCONNECTION: TSQLConnection;
Button1: TButton;
Memo1: TMemo;

procedure Button1Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit1;
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
proxy: TServerMethods1Client;
ClientDataSet1: TClientDataSet;
begin

ClientDataSet1 := TClientDataSet.Create(self);

ClientDataSet1.FieldDefs.Add('ilosc', ftfloat);
ClientDataSet1.FieldDefs.Add('cena', ftfloat);
ClientDataSet1.CreateDataSet;

ClientDataSet1.Append;
ClientDataSet1.FieldByName('ilosc').AsFloat := 10;
ClientDataSet1.FieldByName('cena').AsFloat := 20;
ClientDataSet1.Post;

ClientDataSet1.Append;
ClientDataSet1.FieldByName('ilosc').AsFloat := 120;
ClientDataSet1.FieldByName('cena').AsFloat := 220;
ClientDataSet1.Post;

try
if not self.DATASNAPCONNECTION.Connected then
self.DATASNAPCONNECTION.Open;

proxy := TServerMethods1Client.Create
  (self.DATASNAPCONNECTION.DBXConnection);

//// Wykomentowanie poniższej linii , powoduje że nie pojawia się wyjątek
self.Memo1.Lines.Add(formatfloat('#,##0.00',
proxy.pobierz_sprzedaz(ClientDataSet1)));

finally
proxy.Free;
self.DATASNAPCONNECTION.close;

/// poniższa linia generuje opisany powyżej wyjątek
ClientDataSet1.Free;

end;

end;

end.

0

Może tak napiszesz po ludzku jaki masz problem?

Przede wszystkim to napisz jak należy o co Ci chodzi, a także wstaw kod w odpowiednie znaczniki, bo nikomu nawet się patrzyn na niego nie chce, a już nie mówiąc o próbowaniu zrozumienia go; Oczywiście wstaw jedynie kod, z którym masz problem, a nie cały unit chyba, że z deklaracją modułów też nie radzisz sobie;

No i postaw w końcu pytanie, bo ja w całym tym wątku nie znalazłem znaku ?;

0

Wybacz, ale skoro Ty nie potrafisz napisać wątku po ludzku i przede wszystkim sformatować kod jak przystało na dobrego programistę - zrobię to za Ciebie...

procedure TForm1.Button1Click(Sender: TObject);
var
  proxy: TServerMethods1Client;
  ClientDataSet1: TClientDataSet;
begin
  ClientDataSet1 := TClientDataSet.Create(self);

  with ClientDataSet1 do
    begin
      FieldDefs.Add('ilosc', ftfloat);
      FieldDefs.Add('cena', ftfloat);
      CreateDataSet();

      Append();
      FieldByName('ilosc').AsFloat := 10;
      FieldByName('cena').AsFloat := 20;
      Post();

      Append();
      FieldByName('ilosc').AsFloat := 120;
      FieldByName('cena').AsFloat := 220;
      Post();
    end;

  try
    if not DATASNAPCONNECTION.Connected then
      DATASNAPCONNECTION.Open();

    proxy := TServerMethods1Client.Create(DATASNAPCONNECTION.DBXConnection);
    Memo1.Lines.Add(formatfloat('#,##0.00', proxy.pobierz_sprzedaz(ClientDataSet1)));
  finally
    proxy.Free();
    DATASNAPCONNECTION.close();

    ClientDataSet1.Free();
  end;
end;

Lepiej widać kod? Czy to złośiwość?

Teraz nazwij obiekty i kontrolki po ludzku i znajdź problem; Poza tym napisz łaskawie co to jest DATASNAPCONNECTION oraz gdzie to masz zadeklarowane i gdzie tego i w jaki sposób używasz (i nazwij to po ludzku chyba, że CapsLock Ci się zaciął...);

1 użytkowników online, w tym zalogowanych: 0, gości: 1