Mapping Classes

Wagner,


I am having to separate my Entities on the database and I am following the method defined on help file about that.

I have right now 3 separated TMappingExplorer.

My question is that when working with the Entities, is there any kind of restriction mixing the manager that I am using to load/save the entities, or making cross references?

My current structure right now is all based on the default mapping and the existence of only one database.

Eduardo

Not sure if understood what you want. You can have as many explorers you want, but each object manager can only use one explorer, thus you can't, for example, perform queries on objects/classes in different explorers. What exactly you mean by "mixing managers"?

Let me explain different, for example:


I have Customer, Item, and Order for example.

Order makes reference to Customer and reference to Item(s)

Each one of this entities are mapped in different databaseses (so separated TMappingExplorer).

Is this going to work? Can I create an order and add itens and customer to it?

Right now I get from the only one connect the TObjectManager that I need to use to find/save etc. There is a need to differentiate which Manager I am using? I mean to Find<Orders>  i need to use the TObjectManager that comes from that connection? Or can I use the same for everything?

And how does it work when I have INHERITANCE on Entity?

I am using a lot this inheritance feature, so I have created the base CONTACT and then I have others from descending from it.

However I am trying to separated the databases by project goal, so my standard tables are all together, but I have a Table/entity that INHERITS from CONTACT but needs to be in separated database (same engine Elevatedb however separated databases) since it is not functionally related to the standard database.

The standard database is a generic ERP like structure.

One of the extensions is a "school" ERP software that extends the first database based on inheritance.

Right now everything is in one place, but that looks strange, since I dont want to some customers get tables that are exclusive to other line of business.

I don't think how Aurelius would query two different databases in a single query. The only information classes have is "[Table]" attribute, so only the table name will be included in query. And you can't use two different connections in a single manager.

ok, but what about the table inheritance? 


I have the Contact table registered in one map explorer

and I have one Inheritance of it (Aluno) registered on another map explorer. 

Is this valid? What is going to happen? (I am trying to make a test, however not easy to reach that yet besides I made the changes to support that, thinking that It would work)

It's the same problem, in the parent class is mapped, Aurelius will try to save info in that associated table, and it can't be in a different database than the table used for the descendant class.

sorry to insist, I the case of Aluno, the full inheritance tree is this:


TContato

TContatoFisico(TContato)

TAluno(TContatoFIsico)

The 2 first where registered on "standard" database/mapexplorer and the last one in "school" database/mapexplorer.

You said it cannot be mixed up, I need the first 2 working on standard commonly, however when I have the TAluno in use it could be fully working on the "school" database.

Can I register TContato and TContatoFisico in both MapExplorer? 

Sure that if I was for Find<TContato> from one database is not going to be the same of the other, since the school database only will have TAluno descendants

Ok, let's elaborate, but I still don't know exactly where you want to get.

" however when I have the TAluno in use it could be fully working on the "school" database."
How?
If you do Find<TAluno>, it will perform a query like this (pseudo)

Select from Aluno join ContatoFisico join Contato

to get all info about Aluno. If ContatoFisico and Contato are in different databases, how do you expect this to work?

well, I am still think aurelius makes some magic, this is why i expect it to work :)


however I do understand that a cross-database-query is not possible. That is the case of this join for sure.

I am not going for this anymore, my question is not a little different, on the same topic.

My question is: there is a way to make TAluno works FULLY on its own database? I mean, it is inherited, but in this case to force that when using TALUNO I know that all its components (inherited tables TContato and TContatoFisico) are all together in the same database? 

this will have a drawback for me, since I need to know that I will have 2 find<TContato> possibilities, the ones that comes from the first database and the ones that come from the other database. 

Standard database will bring many kinds of TContato. Scholl database will bring TAluno only. That is better than nothing. I think.

Just thinking in a way to have the inheritance working and have database isolation based on software functionality.

I was wondering, what if I register TContato and TCOntatoFisico in BOTH mapexplorer? does it solve the problem? (sure operations will be isolated and the software needs to know there are 2 databases around, but i believe the model layer could understand that)

If your question is: "can I use the same class in two different mapping explorers?" Then the answer is yes. If you have a table "ContatoFisico" in two different databases, and you want to register class TContatoFisico in two different explorers, there is no problem. Aurelius will build the proper query for the proper database, using the specified mapping. 

Thank you.


This is another problem, but related to the same thread:

I followed the "mapped classes" in help file to create the structure I need.

However I am having problem on the CreateDatabase

If I do this way:

var
  DatabaseManager: TDatabaseManager;
begin
  DatabaseManager := TDatabaseManager.Create(FConnection);
  try
    DatabaseManager.BuildDatabase;
  finally
    DatabaseManager.Free;
  end;

it works creating all the tables on the same database, no separation

if I change to

DatabaseManager := TDatabaseManager.Create(FConnection, FMappingExplorer)

where the MappingExplorer here is the one related to the tables I want defined for this particular database.

I get this error:

ETableMetadataNotFound: OPF Internal Error: Table CONTATOFUNCIONARIO not found in database metadata

That is strange, since the database I am trying to create should not contain this table. I have aroun 30 tables and in this database should have just 2 and this one is not the one.


This usually happens for foreign keys. You might not have added such class in the explorer, but maybe one of the classes added has an association to ContatoFuncionario?

yes, you right. I found one reference for this:


  [Entity]
  [Table('USUARIO')]
  [Id('ID', TIdGenerator.Guid)]
  TEntityUsuario = class(TNaharEntity)
  private
    FId: TGuid;
    FNome: string;
    FLogin: string;
    FSenha: string;

    [Association([TAssociationProp.Lazy], [])]
    [JoinColumn('IDCONTATOFUNCIONARIO', [])]
    FFuncionario: Proxy<TEntityContatoFuncionario>;

Now I understand a little bit more of this.

My question is, even that I dont want to have any automatic join, how can I reference one entity from another one in different database mappings?

for example, I have TEntityUsuario that is in one database.

I need connect the TEntityFuncionario to it, so the Usuario is the one that Log in the system but it is represented by a Funcionario.

What rule should be used here? 

In the example above, problem is that you have mapped FFuncionario (TEntityContatoFuncionario). So, whenever you use TEntityUsuario, Aurelius WILL perform an "automatic query" to retrieve FFuncionario value. You saw for yourself: when you tried to update the database, Aurelius raised an error because it was expecting the TEntityContatoFuncionario table to be in the database.


The workaround would be do not map FFuncionario. Then you could load a TEntityContatoFuncionario from another manager, and assign it to FFuncionario field. BUt that field will not be used by Aurelius at all, it's just a reference for you to use from Delphi code not associated with Aurelius