detect modified objects

Hi,

 
Let me first say that you did a really great job with Aurelius! It's simpel, elegant and extremely powerfull. The TAureliusDataset is a true gem! I think it's the best way to develop business applications using Delphi, and in combination with the datamodeler, it's a unique and powerfull product.
 
I was about to migrate to VS2012 and the Entity Framework, but fortunately I found Aurelius. Now I can stick with Delphi!
 
Just a few questions \ suggestions:
- How does the ObjectManager keep track of changed objects? Can I use this method as well? something like object.ischanged
- Since delphi does not have "partial" classes, all class declarations need to go in 1 unit to prevent circular reference. Is there a beter way to seperate that unit into logical parts? This one unit can get very big and I like to split it up. In my own attempt to create ORM I used an approuch where all the objects could be in seperate units, the reference fields were all just TObject pointers so there was no circular reference. For strong typed association properties I created 1 unit "relations" that defined class helpers for all my objects implementing the strongly typed reference properties. Could something like that be used with Aurelius?
- Is there a way for the datamodeler to reimport the database into an existing model, thereby updating the tables and fields already in the model?
- Does the export of the classdefinitions in datamodeler always overwrite the existing file? How would I go about protecting my customizations in the classes?
- Is there a way to use the MappingExplorer to check if the database is correctly formatted on startup? And if neccesary update the database according to the class definitions.
- I want to use Datasnap to exchange data objects to mobile clients. In XE2 the standard datasnap object marshalling code does not seem thread safe. Is the Aurelius serialising code threadsafe?
- What is the use of the Dict classes the datamodeler can generate?
 
 
 
 

Thanks for yor compliments!
 

It saves previous states internally and compare objects. Unfortunately those methods are private and cannot be accessible in current version.


I don't think so. The only way it would work is if Delphi RTTI makes it completely transparent and treat the class helpers as if they were part of the original class without any difference. But there are additional things like the mapping attributes, properties, fields, I'm afraid it will not work.
From my experience, circular references are not that common, you could separate your units? I mean, an order references a customer, a customer references a country, so one is "used" by another and can be in separated units. Usually that is what happens, but well, maybe your case is different.


No, this is in our todo list actually.


There is no workflow for that, because the whole unit generation is automatic. If you are fine tuning the mapping, maybe you could give us suggestions so that it could be configurable in Data Modeler. If you are adding functionality to your class, maybe you could consider using base classes for your entity classes. In Data Modeler you can configure from which base class your entity class descend from, so you could add code to base classes and make the automatically generated unit to have classes inherited from the base class.


Yes, this was introduced in version 2.0. This functionality was added to TDatabaseManager class.


We didn't perform any heavy tests, but it should be.

 
 Just aliases for the table and field names. So instead of doing something like this:

Find<TCustomer>.Where(TLinq.Equals('Name', 'John'));
you could use this:
Find<TCustomer>.Where(TLinq.Equals(Dic.Customer.Name, 'John'));
 
>It saves previous states internally and compare objects. Unfortunately those methods are private and cannot be accessible in current version.
Would it be an idea to make a method in Objectmanager like: TObjectManager.isChanged(aEntity: Tobject): boolean
That way you could query if an object is changed and will be saved in a flush.
 
>From my experience, circular references are not that common, you could separate your units?
Probably I misunderstood the intent of the manyvalue association. I planned on using this to implement the reverse associations. If an invoice has a customer, customer would have a manyvalue association to invoices. As you can imagine that would create circular reference. Obviously that's not what you intended with the manyvalue associations. When to use manuvalue associations and when not? I can think of uses where you want the aureliusdataset to have detail datasets. But is that the only reason to use the manyvalue associations?
 
>If you are adding functionality to your class, maybe you could consider using base classes for your entity classes
What I like to customize is the property getters and setters. I want custom code to be performed when a property is changed. This would be hard to implement in a baseclass, because I would like to override this behaviour in descending classes. a persistent class animal should have custom code in a property setter but Dog which is a descendent of Animal should overwrite this behaviour.
 
>Yes, this was introduced in version 2.0
Ahhhh was unaware of this new version. Will go try it!
 
 

We can consider adding the IsChanged method to the manager, yes.


About many-valued association, there is no strict rule as "when to use". It's just a way to design your objects. You are not required to use them. I mean, suppose two generic classes, TMaster and TDetail. There is a "conceptual" association between master and detail (one to many) but when implementing this in Aurelius classes you can:
1. Just create an association from detail to master, with a property TDetail.Master
2. Just create a many-valued association from master to detail, with a property TMaster.Details
3. Create both (bidirectional association)
all three options represents the same conceptual association and builds the same database structure. It's just the classes that are different, and it depends on your business model. Usually it makes sense to use many-valued association when there are few details (since they are loaded when the master class is loaded) and/or when your business code usually deals with the details in code (for example, an invoice and invoice items). Usually it does not make sense if you have no reason to use the detail list unless as a query. I mean, there is not much sense in having a TCustomer.Invoices property. You wouldn't want to load invoices for every customer, and you would hardly manage invoices when dealing with a customer (the opposite is true though). So, usually you would just use a query to get the invoices belonging to a customer, but will not create a specific property in TCustomer class for that.

Thanks for all your help