Difference between an O/R Mapper and a code generator?

Posts   
1  /  2
 
    
wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 24-May-2004 12:44:42   

Hi All

I have been investigating the differences between an O/R Mappers and a code generators.

I found this artical: http://dotnetjunkies.com/WebLog/seichert/archive/2003/12/19/4699.aspx

Here i found a few points that i found interesting:

When using a O/R Mapper...

The developer never sees, and thus never worries about this code.

The developer doesn't have to go to a separate tool and say to regenerate the code.

The generated assembly is always up to date.

Are the statements true? Can it be true? confused

My Opinion: 1 - True 2 - False 3 - False

Lets say i add 2 more fields to a table that is represented by an entity - How can the entity always be up to date?

The SQL engine must be dynamic but where does it get it's structure? Unless the entity has build in functionality to scan the underlying table stucture of the entity everytime the entity is created. frowning Sounds time consuming...

Personally i think that those statements are a lot of Bull...well atleast the last 2.

Let me know what you think.

Wayne

netclectic avatar
netclectic
User
Posts: 255
Joined: 28-Jan-2004
# Posted on: 24-May-2004 13:18:02   

I would say an O/R mapper may or may not be a code generator.

Have you read this? http://www.codegeneration.net/tiki-index.php?page=ModelsIntroduction

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39618
Joined: 17-Aug-2003
# Posted on: 24-May-2004 14:13:56   

netclectic wrote:

I would say an O/R mapper may or may not be a code generator. Have you read this? http://www.codegeneration.net/tiki-index.php?page=ModelsIntroduction

The guy running that site invented these categories, they are IMHO not 'general accepted' categories.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39618
Joined: 17-Aug-2003
# Posted on: 24-May-2004 14:23:50   

wayne wrote:

I have been investigating the differences between an O/R Mappers and a code generators.

O/R mapping is a term for a technique used to create a mapping between a class field and a table field. (very simplistic but that's the core). How you achieve that mapping is not important. So you can achieve that through partly generic code and code generation (LLBLGen Pro), solely code generation (Pragmatier), solely generic code and an xml file (Objectspaces (R.I.P.))

I found this artical: http://dotnetjunkies.com/WebLog/seichert/archive/2003/12/19/4699.aspx Here i found a few points that i found interesting: When using a O/R Mapper...

The developer never sees, and thus never worries about this code.

The developer doesn't have to go to a separate tool and say to regenerate the code.

The generated assembly is always up to date.

Are the statements true? Can it be true? confused

Nah. Steve uses in-memory code generation. He generates the code on the fly, compiles it in memory using CodeDOM.

1: true. 2: partly true. Some O/R mappers use attributes (Oh, the joy of applying these to all your 3000 fields stuck_out_tongue_winking_eye ) so developers do not need a code generator (but they need a lot of time and patience). Others use an XML file. So you update the XML file and the mapping changes. (also a trap: it requires a lot of precise management). Some use no mapfile at all, but runtime-reflection (XPO): they persist public properties into tables and adjust the database if necessary. (also fun in production applications). All O/R mapper users need to write the entity classes. Some O/R mappers can generate them for you, including handy properties and nasty interface implementations (You don't want to implement IBindingList or ITypedList on your own classes). That's why LLBLGen Pro generates these classes, because you need them anyway. 3: false. Maintenance has to be done somewhere. Changing a PK in a table, adding an FK, a UC or changing a type of a field, it has to be maintained in the code as well, unless you re-generate code by a tool which takes care of this.

Frans Bouma | Lead developer LLBLGen Pro
netclectic avatar
netclectic
User
Posts: 255
Joined: 28-Jan-2004
# Posted on: 24-May-2004 14:27:47   

Otis wrote:

The guy running that site invented these categories, they are IMHO not 'general accepted' categories.

Fair point but it does show that there's more than 1 way to skin a cat wink

wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 24-May-2004 14:44:51   

The guy running that site invented these categories, they are IMHO not 'general accepted' categories.

What does IMHO stand for? I have seen this so many times already.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39618
Joined: 17-Aug-2003
# Posted on: 24-May-2004 14:46:56   

netclectic wrote:

Otis wrote:

The guy running that site invented these categories, they are IMHO not 'general accepted' categories.

Fair point but it does show that there's more than 1 way to skin a cat wink

hehe simple_smile Yeah. In the past I had some discussion with him about the categories.

IMHO stands for In My Humble Opinion simple_smile

Frans Bouma | Lead developer LLBLGen Pro
wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 24-May-2004 14:59:48   

Otis - How may cleints do you have? If you want to say... wink

Is there a lot of people making use of O\R Mappers? or is it only the bigger companies that are using these kind of technologies?

Wayne

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39618
Joined: 17-Aug-2003
# Posted on: 24-May-2004 17:51:51   

wayne wrote:

Otis - How may cleints do you have? If you want to say... wink

360+ companies in 45 countries at the moment (we use department licenses)

Is there a lot of people making use of O\R Mappers? or is it only the bigger companies that are using these kind of technologies?

Big and small. A lot 2-character .com domains for example and a lot of very small companies. so I think it isn't depending on the size of the company.

O/R mapping in general is not a widely used technique in the .NET world or MS world. Don't forget, a lot of people using microsoft technologies are still hammering in VC++6, VB6 and ASP 3.0 stuff every day simple_smile . .NET is now making progress into these worlds, but it will take some time till the far majority of developers is even on .NET.

Add to that that most MS-oriented developers have never heard of these things: patterns, O/R mapping, domain model. They're tier-oriented, windows DNA focussed. O/R mapping can help you in that model as well, however most developers start with vs.net, look at how data should be handled, stumble into datasets, data-adapters, find designers in vs.net and will work with that. It's close to what they know from the ADO era. They think in stored procedures are called by objects which are called by objects. O/R mapping is the world upside down, no more stored procedures, no more resultset-thinking, just work with the data as the unit you always wanted to have but never had. (it's shocking how many developers simply accept the rude interface of hte dataset (ds.Tables[0].Rows[0]["MyColumn"].Value vs. MyCustomers[0].MyColumn)

But I think the majority will be on O/R mapping sooner or later. If not for the complete application then at least for a part of the application. Which is perhaps a good choice: sometimes resultset thinking brings you better results (reporting for example) than object oriented thinking and vice versa.

I'm also not a supporter of the hard-liners within the O/R mapping world which want everything to be an object and see a database as a big bucket for objects. A more pragmatic approach is much better: for example get all orders and the name of the customer attached to it. In a total OO world you have to subclass order and add the customer name to it. A typed list can easily create it for you.

Frans Bouma | Lead developer LLBLGen Pro
Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 24-May-2004 18:04:51   

Add to that that most MS-oriented developers have never heard of these things: patterns, O/R mapping, domain model.

I think this is because soooo many developers started with VB6. Myself included. I used to thing vb6 was an OO langauge and I could never figure out why C++ developers laughed at me for thinking of myself as an OO developer. Thank god I have seen the light and corrected my thinking.

At one point there were 6.5 million vb6 developers worldwide. Otis, you are so absolutely right in what youre saying. 95% of my software shop is so lost in .net because they are so used to vb6 and 2 tier, ADO, applications.

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 24-May-2004 19:15:47   

Otis wrote:

360+ companies in 45 countries at the moment (we use department licenses) ... But I think the majority will be on O/R mapping sooner or later.

And, I think that the power of your framework and design combined with the incredible value of your pricing scheme makes LLBLGen the harbinger - the apostle, if you will - that will bring O/R mapping to the masses. The world needs a cheap, effective tool like this. Congratulations on LLBLGen's success!

Otis wrote:

Which is perhaps a good choice: sometimes resultset thinking brings you better results (reporting for example) than object oriented thinking and vice versa.

I think some sort of direct, native support for printing needs will be the nail in the coffin. I may be the exception because of the sheer number of times I have to regenerate the LLBL due to time restrictions on the planning phase, but I tend to avoid the typed list/typed view solutions primarily because each time I want to make a change and/or add a new one I have to regenerate the LLBL (honestly a pain in the arse, even with my small 2-person team, simply because of source control issues, and .NETs fun file reference idiosyncracies). Not to mention the current lack of aggregate functionality...

Oh, what joy I would have if I could have simple access to the following functionality:

  1. Create custom collections containing columns from multiple related objects in one call:

Dim myCollection as new CustomCollection
Dim relations as new RelationCollection
Dim fields as new FieldsCollection
Dim predicate as new PredicateExpression

'The fields being added are exposed via shared properties on the entity classes eliminating the need to use field indexes
fields.Add(CustomerEntity.Name) 
fields.Add(OrderEntity.OrderID)
fields.Add(OrderEntity.OrderDate)
fields.Add(OrderDetailEntity.ItemNum)
fields.Add(ProductEntity.Name)

'Add relations
'Create predicate

myCollection.GetMulti(fields, relations, predicate)

  1. Have access to aggregate functions and be able to create a summary report collection similar to (1) above:

fields.Add(CustomerEntity.CustomerID)
fields.Add(OrderEntity.CountOfOrders) 'Count(OrderID)
fields.Add(ProductEntity.AverageOfCost)
fields.Add(ProductEntity.SumOfCost)

  1. Be able to do all of this without regenerating the LLBL or having to subclass or inherit new collections.

Jeff...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39618
Joined: 17-Aug-2003
# Posted on: 25-May-2004 10:19:41   

jeffreygg wrote:

Otis wrote:

360+ companies in 45 countries at the moment (we use department licenses) ... But I think the majority will be on O/R mapping sooner or later.

And, I think that the power of your framework and design combined with the incredible value of your pricing scheme makes LLBLGen the harbinger - the apostle, if you will - that will bring O/R mapping to the masses. The world needs a cheap, effective tool like this. Congratulations on LLBLGen's success!

Thanks! simple_smile

Otis wrote:

Which is perhaps a good choice: sometimes resultset thinking brings you better results (reporting for example) than object oriented thinking and vice versa.

I think some sort of direct, native support for printing needs will be the nail in the coffin. I may be the exception because of the sheer number of times I have to regenerate the LLBL due to time restrictions on the planning phase, but I tend to avoid the typed list/typed view solutions primarily because each time I want to make a change and/or add a new one I have to regenerate the LLBL (honestly a pain in the arse, even with my small 2-person team, simply because of source control issues, and .NETs fun file reference idiosyncracies). Not to mention the current lack of aggregate functionality...

Re-generating code isn't that bad, is it? Sourcecode control is indeed a problem: you have to check out the file before generating code (however, by using subversion or Vault for example, you're not suffering from this). I've changed the vs.net project file generator task performer in the current beta which adds new files to an existing project file, so you don't have to manually add the things, which can make it easier.

Aggregates are indeed lacking, and these are very high on the list. They require a runtime change but it will be worth it.

Oh, what joy I would have if I could have simple access to the following functionality: 1. Create custom collections containing columns from multiple related objects in one call:


Dim myCollection as new CustomCollection
Dim relations as new RelationCollection
Dim fields as new FieldsCollection
Dim predicate as new PredicateExpression

'The fields being added are exposed via shared properties on the entity classes eliminating the need to use field indexes
fields.Add(CustomerEntity.Name) 
fields.Add(OrderEntity.OrderID)
fields.Add(OrderEntity.OrderDate)
fields.Add(OrderDetailEntity.ItemNum)
fields.Add(ProductEntity.Name)

'Add relations
'Create predicate

myCollection.GetMulti(fields, relations, predicate)

If you would load the stuff into a datatable, I'd agree, but how does your example work? I mean: the fields should be part of an entity, right? So properties in that entity should be present, at compile time, so dynamically adding fields is not doable, I think.

  1. Have access to aggregate functions and be able to create a summary report collection similar to (1) above:

fields.Add(CustomerEntity.CustomerID)
fields.Add(OrderEntity.CountOfOrders) 'Count(OrderID)
fields.Add(ProductEntity.AverageOfCost)
fields.Add(ProductEntity.SumOfCost)

Will come in the next runtime upgrades first, which will be followed by a gui update to add this functionality to the designer as well.

  1. Be able to do all of this without regenerating the LLBL or having to subclass or inherit new collections.

What are the real problems with re-generating the code, could you please elaborate on that?

Frans Bouma | Lead developer LLBLGen Pro
Fishy avatar
Fishy
User
Posts: 392
Joined: 15-Apr-2004
# Posted on: 25-May-2004 13:45:30   

Otis wrote:

jeffreygg wrote:

Oh, what joy I would have if I could have simple access to the following functionality: 1. Create custom collections containing columns from multiple related objects in one call:


Dim myCollection as new CustomCollection
Dim relations as new RelationCollection
Dim fields as new FieldsCollection
Dim predicate as new PredicateExpression

'The fields being added are exposed via shared properties on the entity classes eliminating the need to use field indexes
fields.Add(CustomerEntity.Name) 
fields.Add(OrderEntity.OrderID)
fields.Add(OrderEntity.OrderDate)
fields.Add(OrderDetailEntity.ItemNum)
fields.Add(ProductEntity.Name)

'Add relations
'Create predicate

myCollection.GetMulti(fields, relations, predicate)

If you would load the stuff into a datatable, I'd agree, but how does your example work? I mean: the fields should be part of an entity, right? So properties in that entity should be present, at compile time, so dynamically adding fields is not doable, I think.

Yea, load it into an untyped datatable. I don't see how you would create a typed collection on-the-fly.

You should not have to regenerated llblgen projects since it will generate the correct sql depending on the fields you add to your fieldscollection.

wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 25-May-2004 13:53:56   

If you would load the stuff into a datatable, I'd agree, but how does your example work? I mean: the fields should be part of an entity, right? So properties in that entity should be present, at compile time, so dynamically adding fields is not doable, I think.

I think it would be nice to be able to this:

Dim myCollection as new CustomCollection
Dim relations as new RelationCollection
Dim fields as new FieldsCollection
Dim predicate as new PredicateExpression

'The fields being added are exposed via shared properties on the entity classes eliminating the need to use field indexes
fields.Add(CustomerEntity.Name)
fields.Add(OrderEntity.OrderID)
fields.Add(OrderEntity.OrderDate)
fields.Add(OrderDetailEntity.ItemNum)
fields.Add(ProductEntity.Name)

'Add relations
'Create predicate

myCollection.GetMulti(fields, relations, predicate)

It will add a lot of power to LLBLGen - to be able to create custom updatable queries at runtime that is dependent on already existing fields that are relationaly linked.

For example define the field 'columns' as above but add the FK relations in asswell.

like for example something like this:

fields.Add(CustomerEntity.Name)
fields.Add(OrderEntity.OrderID)
fields.Add(OrderEntity.OrderDate)
fields.Add(OrderDetailEntity.ItemNum)

Relation.Add(CustomerEntity.CustomerID,OrderEntity.CustomerID)

Then access the field not via properties but via a method like.wink

Entity.fieldbyname('Name')

Wayne

netclectic avatar
netclectic
User
Posts: 255
Joined: 28-Jan-2004
# Posted on: 25-May-2004 14:03:25   

Yea, that's exactly the kind of functionality i was looking for a while ago. Part of the app i'm working on allows the end user to extend/modify the database but everything is defined in our own "system" tables.

Currently, i've got a mixed bag of Enitities/Collections for accessing the core system tables and good old dataset/adapters for accessing the dynamic bits. It would have been nice to have it consistent but such is life rage

wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 25-May-2004 14:06:58   

It sounds like you are doing something like userdefinable tables - where a user can define a custom table for batching operations?

But the user table does not really exist as they are mapped to the actual table field. (Almost like an updatable View) This is a very cool feature for users.sunglasses

  • I did something like this before in Delphi with Paradox(Never again please) frowning

The WANTEDwink stuck_out_tongue_winking_eye feature that we are discussing above will fit it perfectly for something like this.

Fishy avatar
Fishy
User
Posts: 392
Joined: 15-Apr-2004
# Posted on: 25-May-2004 14:25:53   

wayne wrote:

Then access the field not via properties but via a method like.wink

Entity.fieldbyname('Name')

Wayne

or maybe Entity.FieldByEntityName(CustomerEntity.Name)

Though, I don't exactly how that would work.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39618
Joined: 17-Aug-2003
# Posted on: 25-May-2004 14:52:58   

wayne wrote:

If you would load the stuff into a datatable, I'd agree, but how does your example work? I mean: the fields should be part of an entity, right? So properties in that entity should be present, at compile time, so dynamically adding fields is not doable, I think.

I think it would be nice to be able to this:

Dim myCollection as new CustomCollection
Dim relations as new RelationCollection
Dim fields as new FieldsCollection
Dim predicate as new PredicateExpression

'The fields being added are exposed via shared properties on the entity classes eliminating the need to use field indexes
fields.Add(CustomerEntity.Name)
fields.Add(OrderEntity.OrderID)
fields.Add(OrderEntity.OrderDate)
fields.Add(OrderDetailEntity.ItemNum)
fields.Add(ProductEntity.Name)

'Add relations
'Create predicate

myCollection.GetMulti(fields, relations, predicate)

It will add a lot of power to LLBLGen - to be able to create custom updatable queries at runtime that is dependent on already existing fields that are relationaly linked.

For example define the field 'columns' as above but add the FK relations in asswell.

like for example something like this:

fields.Add(CustomerEntity.Name)
fields.Add(OrderEntity.OrderID)
fields.Add(OrderEntity.OrderDate)
fields.Add(OrderDetailEntity.ItemNum)

Relation.Add(CustomerEntity.CustomerID,OrderEntity.CustomerID)

Then access the field not via properties but via a method like.wink

Entity.fieldbyname('Name')

You can already do that (Entity.Fields["Name"] ), but you can't create a new entity that works like this: Entity.Name as a new dynamic property.

Also multi-table entity fetches are not yet supported.

Frans Bouma | Lead developer LLBLGen Pro
netclectic avatar
netclectic
User
Posts: 255
Joined: 28-Jan-2004
# Posted on: 25-May-2004 14:58:59   

wayne wrote:

It sounds like you are doing something like userdefinable tables - where a user can define a custom table for batching operations?

But the user table does not really exist as they are mapped to the actual table field. (Almost like an updatable View) This is a very cool feature for users.sunglasses

Yes, something like that. The existing app (Delphi Win32) comes with a designer that lets users modify existing tables, add new tables/views etc. but everything is defined in our system tables. So at run time i have no idea what the actual structure of the database might be and have to query our system tables to find out.

The users love it, but it's a nightmare for us poor developers rage

On top of that sits a screen designer, that let's the users build their screens so what i end up with in my asp.net app is a delphi dfm stream which i have to parse and output as a pretty webpage.

Again, all very nice and flexible for the users but give me a nice static app to work on anyday!

Speaking of Paradox... Otis, when can we expect a Paradox driver? wink

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39618
Joined: 17-Aug-2003
# Posted on: 25-May-2004 15:18:37   

Paradox? simple_smile [insert silly prank here]

Hmm, isn't that an ISAM db? (like DBase)

Frans Bouma | Lead developer LLBLGen Pro
wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 25-May-2004 15:33:22   

Beter known as Crapadox.simple_smile Big brother of DBase.

1 table = 1 file. 1 PK = 1 file 1 Idx = 1 file 1 Blob \ Memo = 1 file 1 lck file per directory 1 net file per Networked system. Referention Integrity per table = 2 files. Passwords per table.

No system tables.

Requires BDE even when using ADO. ADO = Read BDE = Read + Write ADO + BDE = Read + Write

Loves Corruption And Index out of date errors.

Sounds like fun doesn't it. wink

Rather use Text files - works better!

netclectic avatar
netclectic
User
Posts: 255
Joined: 28-Jan-2004
# Posted on: 25-May-2004 15:39:47   

Don't forget the .lck and .net files.

My first ever commercial bit of software used a "multi-user" paradox db frowning

wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 25-May-2004 15:45:44   

Paradox = HELL. Interbase = HEAVEN compared to paradox. SQL Server = 7th HEAVEN. (I always Remember IB to be very nice untill i treid to work with it again.)

When using Paradox... Had enough of rebuilding Tables and indexes. Trying to fix corruption.

Deleting *.lck files and .net files. Counting fisical rows to check if the table's row count isn't lying - (Corrupt but it doesn't know it.)

Networking - what a nightmare!!

To top this - it still gets used in a commercial enviroment - Payroll System.

So when can we expect the driver? stuck_out_tongue_winking_eye Tomorrow would be nice. wink

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39618
Joined: 17-Aug-2003
# Posted on: 25-May-2004 15:51:18   

heh simple_smile I'm not even sure there is an OleDB driver for Paradox. All ISAM db's should be put to rest somewhere far far away. They were nice when a computer was a thing that wasn't connected to anything except the power socket. simple_smile

The thing is called paradox for a reason I think wink

Frans Bouma | Lead developer LLBLGen Pro
netclectic avatar
netclectic
User
Posts: 255
Joined: 28-Jan-2004
# Posted on: 25-May-2004 16:10:37   

Don't knock if, not only does it have it's own programming language but it even has it's own DAY!! stuck_out_tongue_winking_eye

1  /  2