UnDiUdin
UnDiUdin

Reputation: 15394

Simple OODesign question: how to query data from multiple objects?

I have been assigned the task of refactoring a legacy database application and I am trying to create objects that incapsulate the old code. It is the first time I use real OODesign, for now I just used OO to encapsulate some legacy login and refactor a subset of functionalities from an application. (Now it is the classic client server app with all the business logic in the UI, the idea is to make it multilayer in order to use the clients against an application server and eventually write a web interface.)

I'll make an simplified example to explain what I want to accomplish:

I have many instances of this class:

type
  TCustomer = class(TObject)
  private
    FOrders: TList<TOrder>; // or how do implement this?
    // the idea is that the TCustomer "owns" the TOrder, anyway in the 
    // legacy DB I just have an orders table with FK to the customer table
    // not the contrary. 
    // But if I do that the Customer object "loses" the TOrders???
    [...] // Many other fields
  public
    [...]
  end;

How do I query the Orders of all the customers? Imagine I want to query all the orders from September 2007.

If I have 10000 TCustomer objects I don't want for sure to create them all (that means retrieveing them all from the database: I would retrieve too many info I don't need).

In the current software of course it is done with a simple query to the orders table.

But how this is accomplished in the OO world?

Which is the approach you suggest me?

Moreover: in refactoring a this kind of database applications do you suggest using an ORM (that means creating a new database and migrating all the data) or simply use existing DB (that is not bad in my case)?

Upvotes: 4

Views: 668

Answers (4)

AlexSC
AlexSC

Reputation: 1933

Take a look on DORM at https://code.google.com/p/delphi-orm/.

Other answers correctly stated that what you want (at least sometimes) is lazy loading.

However, it seems to me that in your particular example, what you want is a query (not lazy loading) that selects some instances (TOrder) that are related to other (TCustomer) under a certain select criteria (the month and year). In this case you would not use the property TCustomer.Orders (lazy loading) because this one loads all the orders.

No matter what framework you will use (and I agree with others, you need to choose or build one), it must allow you to build and run a query over the persisted objects and their relationships.

Upvotes: 1

NaN
NaN

Reputation: 9104

Try TMS Aurelius, which is a very complete framework for Object Oriented persistence, search and data base serialization.

Upvotes: 0

Marjan Venema
Marjan Venema

Reputation: 19356

I agree with dark_charlie that doing this kind of work is not trivial or simple and I would recommend going with a framework.

Apart from the two commercial ones for Delphi listed on the Wikipedia page he mentions, there are several Open Source ones for Delphi as well.

A couple of others are mentioned in the answers to this stack overflow question: ORM for DELPHI win32

Most if not all will support using them against an existing database, though that may require some coding/handiwork on your part to tell the framework how to map your classes to the existing tables and columns.

Upvotes: 2

Karel Petranek
Karel Petranek

Reputation: 15164

The solution is not trivial and I wouldn't call it simple. What you are looking for is called lazy loading.

The basic idea is to create a proxy object that will load the objects from database on request and preferably do some smart caching as well. In your case this object would be your own implementation of TList - just derive from it and override corresponding methods to load and construct objects from the database.

There are mature frameworks that do object-relational mapping, including lazy loading. One of such examples is Hibernate. If you are allowed to use .NET within your Delphi application, you may check a .NET port of it called NHibernate. Another option would be to use iBatis or any of the frameworks listed at Wikipedia.

Upvotes: 4

Related Questions