> > data isn't read into the objects out of nothing when you want it,
you 
> > have to order some code to get it
> 
> In our persistent framework, merely copying a object's 
> properties doesn't cause objects to load, once on those 
> properties is "dotted", that causes the object to be 
> transparently loaded.  It's sometimes a VERY efficient way to 
> deal with objects, and sometimes not.  When we're carrying 
> lists of objects around, and only referencing some attributes 
> of them, we don't load the other attributes (and related 
> objects)--which is fast.  When we do deref those objects, the 
> get loaded (once per scope) in multiple transactions--which is slow.

        good point, lazy loading (or load on demand or whatever term is
correct) is indeed a way to load data 'on the fly' while you're not
aware of it. The point I was trying to make however was the initial
object data you start the 'dotted' traversal of relationship with, how
is that one loaded? -> you have to ask for it. 

        I did a little thinking on 'transparent persistence' this
morning, and I came up with this:

        If you look at your application as if the entities in the
database are apparently in memory, loaded into objects, you shouldn't be
aware of the fact an entity is loaded, an entity is saved, an entity is
deleted... like a set of string objects in a hashtable. 
        
        This is of course great, there are a few practical problems:
deleting and saving. Fetching entities in the background is not that
hard. You even could have a system like the hashtable: 

CustomerEntity c = Customers["CHOPS"];

which fetches the customer CHOPS from the database (or in core lazy
loaded objectset). 

        When to save an entity? IMHO the only right place is when the
entity is altered, save it directly. (otherwise you run the risk of
loosing data when the system crashes, the state in memory has to be
propagated back to the database, they have to be kept in sync). This is
of course very hard to do with transactions pending, users who want to
cancel etc. Deleting is also a problem, is (silly example)
Customer.Orders.Remove(myOrder); removing the order from the db or just
from the collection so it won't be displayed for example?

        Besides the problems of keeping the db in sync with the
in-memory objects (especially in a multi-desktop application), these
problems are very hard to solve. 

> But the important point here is that NONE of our code knows 
> how objects are joined together, what table(s) they are in, 
> what the column names, or indeed the data types of the 
> columns are.  

        Same here, except for the joined together part. See below.

> If an object happens to span a couple of 
> tables, and reference a dozen more, querying for the 
> interesting objects and loading them (lazily) happens 
> automatically with code like this:
> 
> string StateToFind = 'MO';
> Framework.Query findCustomers = new Framework.Query("this", "that");
> 
> findCustomers.SetId(Customers.Attributes.CustomerId);
> findCustomers.AddWhereClause(findCustomers.FormatEquals(Addres
> s.Attributes.State, StateToFind));
> findCustomers.AddWhereClause(findCustomers.FormatBegins(Custom
> er.Attributes.LastName, "Brooks");
> findCustomers.AddOrderBy(Customer.Attributes.LastName);
> findCustomers.AddOrderBy(Customer.Attributes.FirstName);
> findCustomers.AddOrderBy(Customer.Attributes.AddedWhen, DESCENDING);
> 
> Framework.IPersistantObjectList matchingCustomers = 
> findCustomers.GetList(50);
> 
> will automatically generate this SQL for SQL Server (and the 
> appropriate other formats for Informix, and DB2, just by 
> sniffing the connection
> provider):

        Interesting query language. :) Mine is much more verbose, as I
wanted to stay away from 'SQL'. 
        
        Your example however has an interesting problem. What if a
customer has 2 relationships with Address: visitor and billing  address?
How are you going to specify in your query that you want to filter on
visitor address and not also billing address? 

        This requires knowledge of the join, more exact: knowledge of
the fields in the relationship. How else are you going to be able to
specify that you want to join address on customer.VisitorAddressID  and
not on customer.BillingAddressID ? 

        I couldn't solve this without adding information about the join
in the relation objects I use to specify join paths so people could
specify which relationship to use in the query. Do you have a different
solution to this? 

        I mention this because it shows that IMHO it is required
developers know the relationships between objects, perhaps not the
entity tables that are used to construct the entity itself, but they do
need to know which mandatory fields to set to a value, for example in
the silly example of 'Order' fk to Customer and Employee. Order will
most likely be added to Customer.Orders, which is natural (but also
assumes knowledge of customer-order relationship), however
Order.EmployeeID needs a value otherwise the insert of Order will fail. 

        IMHO that is not solvable without knowledge of the
relationships, but perhaps I miss something.
        
> SELECT TOP 50
>         Customers.Id
>         , Customers.LName
>         , Customers.FName
>         , TransLog.AddDate
> FROM Customers
> INNER JOIN Addresses
>         ON Customers.CustAddrId = Addresses.Id
>       AND Addresses.State = 'MO'
> INNER JOIN TransLog
>         ON Customers.Id = TransLog.ObjectId WHERE
>         Customers.LName LIKE 'Brooks%'
> ORDER BY
>         Customers.LName ASC
>         , Customers.FName ASC
>         , TransLog DESC;

        Interesting, do you move the Addresses.State = 'MO' to the WHERE
clause if the joins need to be LEFT JOIN's in the case of weak
relationships? It is my understanding that it does make a difference
having an extra predicate in the ON clause vs having it in the WHERE
clause in the case of LEFT JOIN's. Or did you find different results?

                FB

===================================
This list is hosted by DevelopMentorŪ  http://www.develop.com
Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 26 Jan 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to