LinlindembergCz / DEntityFramework

DEntityFramework é o EntityFrameWork for Delphi Language
29 stars 8 forks source link

Parabéns!!! #1

Open ghost opened 5 years ago

ghost commented 5 years ago

Muito interessante seu projeto... Eu percebi que se o campo PK de uma tabela não tiver o Nome 'ID' ele não faz o mapeamento da classe... Armazenar os fields num TObjectDictionary<string, TColumnMIK> nao resolveria este ponto?

Grato...

ghost commented 5 years ago

`// Um caminho para pegar o campo PK dentro do SQL montado // para ser usado no CreateDataSet

TEntityFDConnection = class(TEntityConn) private FTipoCon: FDConn; {Inclui para pegar o campo PK da tabela passada no SQL do CreateDataSet} ++ FPkField: String; ++ function GetPrimaryKey(const aTableName: String): String;

function TEntityFDConnection.GetPrimaryKey(const aTableName: String): String; var LQuery: TFDQuery; LSql: String; begin Result := 'ID'; // Caso não pegue nada mantenho seu antigo valor LQuery := TFDQuery.Create(nil); LQuery.Connection := CustomConnection as TFDConnection;

try LSql := 'SELECT RDB$FIELD_NAME ' + SlineBreak + 'FROM ' + SlineBreak + 'RDB$RELATION_CONSTRAINTS C, ' + SlineBreak + 'RDB$INDEX_SEGMENTS S ' + SlineBreak + 'WHERE ' + SlineBreak + 'C.RDB$RELATION_NAME = ' + aTableName.QuotedString + ' AND ' + SlineBreak + 'C.RDB$CONSTRAINT_TYPE = ' + ('PRIMARY KEY').QuotedString + ' AND ' + SlineBreak + 'S.RDB$INDEX_NAME = C.RDB$INDEX_NAME ' + SlineBreak + 'ORDER BY RDB$FIELD_POSITION'; LQuery.SQL.Text := LSql; LQuery.Open; if LQuery.RecordCount > 0 then begin LQuery.First; Result := LQuery.Fields.Fields[0].AsString; end; finally LQuery.Free; end; end;

{ Implementando no CrateDataSet}

function TEntityFDConnection.CreateDataSet(prsSQL: string; Keys:TStringList = nil ): TFDQuery; var qryVariavel: TFDQuery; J : integer; begin qryVariavel := TFDQuery.Create(Application); with TFDQuery(qryVariavel) do begin Connection := CustomConnection as TFDConnection; SQL.Text := prsSQL; Prepared := true; open; ++ FPkField := GetPrimaryKey((TFDQuery(qryVariavel) as IProviderSupport).PSGetTableName); UpdateOptions.AutoIncFields:= FPkField; Fieldbyname(FPkField).ProviderFlags :=[pfInWhere, pfInKey]; Fieldbyname(FPkField).Required := false; UpdateOptions.UpdateMode := upWhereKeyOnly;

for J := 0 to Fields.Count-1 do
begin
  if UpperCase( Fields[J].FieldName) <> FPkField then
  begin
    Fields[J].ProviderFlags:=[pfInUpdate];
  end;
end;

end; result := qryVariavel; end;

// Desta forma pego o campo PK seja qual for o seu nome...

// Isto eu fiz para usar o seu Entity apenas para abstrair a criacao das querys numa factory de dataset que criei...

// Espero lhe seja util`

ghost commented 5 years ago

Funcionando perfeitamente para alimentar um BindSourceDB no FMX

Screenshot at May 11 19-22-52

ghost commented 5 years ago

Agora vou partir para o UPdateDirect que parece não estar recebendo os valores dos fields...

LinlindembergCz commented 5 years ago

Boa tarde meu caro, com relação a....

"Eu percebi que se o campo PK de uma tabela não tiver o Nome 'ID' ele não faz o mapeamento da classe"

Esse é uma ORM inspirado pelo EntityFrameWork do .Net , sendo assim, lá o campo ID é obrigatório como boa pratica. E de fato é interessante que cada tabela tenha seu campo ID.O mapeamento dá prioridade à classe sobre a tabela e não o contrário. Esse método CreateDataSet sofrerá modificação de modo a elimina a tríplice DataSet + Provider + ClientDataSet ..... a tendência do framework será fornecer como ResultSet um DataSet ou Json.

"Funcionando perfeitamente para alimentar um BindSourceDB no FMX "

Legal, você conseguiu integrar o Bind do delphi com o ORM... interessante, depois vou estudar como voce fez.

Alem disso, o ORM tambem vem implementado com um mecanismo de Bind, veja Service.Utils.DataBind.pas

Da forma que voce fez seu Linq tambem funciona, mas tambem poderia ser assim:

u:= Usuario; From(u).Where(u.Bloqueado = 'N' and u.Id = FIDUsuarioLogado.ToString ).Select([u.Id,u.Usuario,u.Senha,...]);

"agora vou partir para o UPdateDirect que parece não estar recebendo os valores dos fields. "

UpdateDirect atua sobre a Entidade do TDataContext , veja:

TAutoMapper.GetFieldsPrimaryKeyList(FEntity) <<--

Obs: quando você realiza uma consulta pelo ORM é guardado uma instancia do objeto Entidade internamente e o ORM trabalha com ele para efetuar insert, Update e Delete

Aconselho dá uma boa olha com no Projetos exemplos... principalmente projectDDD .dpr

Boa sorte e sucesso!

Em qua, 15 de mai de 2019 às 04:41, timanagement notifications@github.com escreveu:

Reopened #1 https://github.com/LinlindembergCz/DEntityFramework/issues/1 .

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/LinlindembergCz/DEntityFramework/issues/1?email_source=notifications&email_token=ACSNEO7EYNTE7FNFRPEHOBDPVO5B7A5CNFSM4HMFQF7KYY3PNVWWK3TUL52HS4DFWZEXG43VMVCXMZLOORHG65DJMZUWGYLUNFXW5KTDN5WW2ZLOORPWSZGOROO47VA#event-2342375380, or mute the thread https://github.com/notifications/unsubscribe-auth/ACSNEO6PHAJ2MMTYW4LYV3LPVO5B7ANCNFSM4HMFQF7A .