|
Marc,
I tend to get a little fired up talking about this stuff. I believe strongly in code generation and a strongly typed model, and I think I have some good arguments to back up my opinions. But at the end of the day, if you can get the job done quickly and effectively in your own way, then more power to you. I always start a project trying to make it a work of art, but in the end, I just want to get the thing done and working on time. I enjoy these debates emmensely because it keeps my mind open to other ways of doing things. There are definitely some advantages of a runtime system, especially for smaller projects. If I was doing a small app and I just wanted to get the damned thing working as fast as possible, there are times would I would prefer to use such a system. However, in the kind of application I've been doing at work, I'm dealing with 100s to 1000s of tables, and I couldn't survive with a system like the one you're using. I guess there's never one perfect solution for every project that uses a database. There are many options and you have to use the one that makes sense.
|
|
|
|
|
JustinGreenwood wrote: I tend to get a little fired up talking about this stuff.
Me too!
JustinGreenwood wrote: I have some good arguments to back up my opinions.
Yes you do.
JustinGreenwood wrote: I enjoy these debates emmensely because it keeps my mind open to other ways of doing things.
As do I, but I keep having problems wrapping my head around the advantages of ORM--barring the intellisense (a definite advantage) and possibly the strong typing in certain situations that you pointed out.
JustinGreenwood wrote: I couldn't survive with a system like the one you're using.
hehe, Interesting. Well, like I said, if you ever want a demo, I've got a gotomypc account (if I can remember where I wrote down the passwords!) and I'd be happy to give you a demo (probably overly simplistic, but what the heck).
Marc
Pensieve
Some people believe what the bible says. Literally. At least [with Wikipedia] you have the chance to correct the wiki -- Jörgen Sigvardsson
|
|
|
|
|
Marc,
I would be interested in a demo. I wrote the article http://www.codeproject.com/aspnet/NHibernateBestPractices.asp[^], and am a bit biased towards NHibernate, but I would love to see a different approach. Correct me if I'm wrong, but it sounds like your approach is more inline with the Ruby on Rails approach of "convention over configuration."
IMO, I think we* have a lot to learn from the Rails approach and would like to see a port of the Rails approach to .NET. (I know Castle MonoRail exists, but it's still not nearly as automated as Ruby on Rails.)
Billy @ http://www.geekswithblogs.com/billy
* "We" includes all developers who write SQL code, stored procs, ADO.NET, any kind of thick data-tier, and even NHibernate mapper writers!
|
|
|
|
|
>Well, if you ever want a demo, let me know, and we can discuss the pros and cons (which of course, >there are, just like anything else) to the tools I'm using.
Can you post a demo somewhere? or if you dont mind send me a copy of it joao@araujofamily.org.
I am really interested in the way you do it. Though, I have to agree with
Justin, I work with 100 tables databases, which are complicated to work with
the way you do. I also feel confortable with ORM(Hibernate, NHibernate).
Anyway, I think it is of some help looking into yours approach.
Thanks,
Joao Araujo,
Joao Araujo
|
|
|
|
|
JustinGreenwood wrote: Once you've used any strongly typed framework along with a code generator in a large application, you will never go back.
Maybe it is "Once you've used strongly typed ... you can't ever go back". A strongly typed system tends to tie your hands and restrict your ability to change things, after a while you get used to it and think your hands were born that way (tied).
There are so many times I saw suggestions to make changes to some badly designed strongly typed systems, the answers are typically "we can't do it".
My articles and software tools
|
|
|
|
|
Yep reminds me of when I went for a job interview once and asked about their software reuse. The manager replied that they had a terrific reuse program -- all the parameters where passed in as void pointers and the results were returned as void pointers.. That way they could pass in anything and turn the results into anything they wanted -- 100% reuse -- He was so proud of his team..
I snatched my resume from his hands turned on my heel and left his office as quickly as I could.. I could almost hear the flying monkey theme from the Wizard of Oz as left the building...
All science is either physics or stamp collecting.
|
|
|
|
|
ReleaseTheHounds wrote: all the parameters where passed in as void pointers and the results were returned as void pointers..
Interesting. Like passing objects everywhere in C#, eh?
I guess one of the main arguments of ORM is the strong typing, which puts one right into the argument as to whether weak or strong typing is better. And there's no easy answers.
Marc
Pensieve
Some people believe what the bible says. Literally. At least [with Wikipedia] you have the chance to correct the wiki -- Jörgen Sigvardsson
|
|
|
|
|
Did it look like this?
abstract public class GenericDAL
{
public abstract object[] Execute(string actionName, params object[] parameters);
}
|
|
|
|
|
Xiangyang Liu wrote: Once you've used strongly typed ... you can't ever go back
Xiangyang Liu wrote: the answers are typically "we can't do it".
That always amazes me, when a system becomes so inflexible that the programmers will say that. Although, it is easy to create an architecture that needs to be basically tossed out and redesigned to meet some new requirements, but that's primarily because shortcuts were taken to the OOD. Which I've done myself numerous times.
Marc
Pensieve
Some people believe what the bible says. Literally. At least [with Wikipedia] you have the chance to correct the wiki -- Jörgen Sigvardsson
|
|
|
|
|
Marc, let me throw this into the fire. EntitySpaces, a new architecture I've created with others through EntitySpaces LLC generates SQL on the fly, and it gives it back to you so you can see it if you so desire. You can also write an EntitySpaces project for Oracle and run the EXACT same code on Access, Oracle or MySQL without recompiling, it's merely a connection string change. However, it is all strongly typed, but very lightweight, and generateable. We use inheritance to avoid regeneration errors, your custom classes inherit from the generated classes, you never hand edit the base (generated) classes, you just override any methods or properties in your custom class. Thus, when you look at your custom code classes they are either empty (because the generated class does it all) or they only contain your real business logic which makes it very nice indeed.
The nice thing about this approach is there are never runtime errors. The code compiles 100% clean and we never use hard code fields names, "EmployeeID" rather we use Employees.Columns.EmployeeID. You can write a query like this, via intellisense, and it runs on any database:
public partial class EmployeesQuery: esEmployeesQuery
{
public bool CustomLoad()
{
Select(EmployeeID, FirstName, LastName, TitleOfCourtesy)
.Where
(
Or(LastName.Like("%A%"), LastName.Like("%O%")),
this.BirthDate.Between("1/1/1940", "1/1/2006")
)
.OrderBy(LastName.Descending, FirstName.Ascending);
return this.Load();
}
}
It's amazing how productive we are with this approach, so easy a child could do it, and it's generated in seconds, and can be regenerated in seconds if/when the schema changes.
Employees entity = new Employees();
entity.AddNew();
entity.FirstName = this.txtFirstName.Text;
entity.LastName = this.txtLastName.Text;
entity.Save();
Look at that code above, spoon fed via intellisense, it functions with or without stored procs, you get to choose, and runs on any provider, strongly typed, serializable and so forth ...
Mike Griffin
EntitySpaces LLC
http://www.entityspaces.net
-- modified at 10:31 Wednesday 26th April, 2006
|
|
|
|
|
You can also write an EntitySpaces project for Oracle and run the EXACT same code on Access, Oracle or MySQL without recompiling, it's merely a connection string change.
Mike, I hope you meant that if you wrote a project for Oracle, you have to keep your db exactly the same on mysql, access, sqlserver etc.
It's hardly ever just changing the connection string. If I have a project on SqlServer, with GUID's, bitfields and the like, no way I'll be able to use that same project on Oracle without converting data somewhere: Oracle doesn't have a GUID type nor a bittype.
We use type converters behind the scenes so you can keep your entity code like:
myCar.IsCabrio = true;
and be able to save that myCar in Oracle, or whatever DB, though it'll never be just a switch of a connection string for the developer. At runtime, sure, just switch between adapter instances, per call, and you can access whatever db you like, but during development, it's not possible.
Or the DB has to obey strict rules like only use types from this small list etc. and that's too restrictive.
--
Lead developer LLBLGen Pro: http://www.llblgen.com
Only the true wise understand the difference between knowledge and wisdom.
|
|
|
|
|
Actually, we have a huge NUnit Test suite that runs against EntitySpaces available for download to all registered users. We run a huge battery against Oracle, Access, Microsoft SQL, and MySQL using the same exact binary code, the only difference being the EntitySpaces connection string entry in the config file, which also indicates whether you want to use stored procedures or dynamic sql, and whether you want ADO.NET command based transactions or enterprise distributed transactions, all in all it's like 30 some odd configurations all driven by the config file.
You are correct that you have to use a subset of all available datatypes of course, however, it's very forgiving, we use a 'bit' for boolean in SQL and in Oracle it's represented by a 'number' and it all works fine. EntitySpaces does an excellent job with provider independence actually.
See http://www.entityspaces.net/portal/Documentation/TestSuiteGettingStarted/tabid/99/Default.aspx[^]
Maybe you can study our techniques and improve LLBLGen if you're having trouble with provider independence?
|
|
|
|
|
Though are these conversions hardcoded? I mean, if I have an entity class with a boolean field Foo, and I want to save it into oracle, I have to have a field NUMBER(1,0) there? What if I want to map it onto CHAR(1) with Y and N ?
I also just switch a connection string to test a set of tests against oracle or sqlserver or other database, though don't have to limit myself to a subset of types nor does the db schema have to obey restrictions, while your schemas IMHO have to obey restrictions as in: it won't work with every legacy db / existing db out there.
--
Only the true wise understand the difference between knowledge and wisdom.
|
|
|
|
|
No, the mappings are dynamic, we use a rather interesting feature of ADO.NET to accompish it, it's a very powerful approach actually, it will darn near map anything to anything ...
|
|
|
|
|
I must be missing a part of the ADO.NET manual then, because I don't recall a feature which can map any type onto any other type for data persistence/retrieval.
Also, if it's true what you're saying, why do you still need a subset of the types?
--
Lead developer of LLBLGen Pro: http://www.llblgen.com
Only the true wise understand the difference between knowledge and wisdom.
|
|
|
|
|
I said "darn near" that's why
|
|
|
|
|
But you're not going to explain which feature you alone have found in ado.net to do this?
--
Lead developer of LLBLGen Pro: http://www.llblgen.com
Only the true wise understand the difference between knowledge and wisdom.
|
|
|
|
|
No, being a weekend warrior and not a full timer like yourself I need an edge ...
|
|
|
|
|
Haha Ok, I give you that :P
To help you get some sleep over the weekend: I use TypeConverter derived classes to convert back/forth between types. These classes are assigned to an entity field, so you can thus effectively map any .NET type you want onto any .NET type. The core sees the type converters and uses them to convert values back/forth when values are read or when values are written. This is completely transparent so I can map a string to an XmlDocument and back or a blob to a real Image object and back etc. and thus choose with the proper converter on which native db type I'll map it.
--
Lead developer of LLBLGen Pro: http://www.llblgen.com
Only the true wise understand the difference between knowledge and wisdom.
|
|
|
|
|
Btw, I see you got over 50 votes in the last half hour... impressive!
--
Lead developer of LLBLGen Pro: http://www.llblgen.com
Only the true wise understand the difference between knowledge and wisdom.
|
|
|
|
|
We alerted our user base to poll, given that we get a 1,000 downloads a week it I expect it to continue climbing for a while. So many times MyGeneration is nominated for things and we never know about it until the contest is over ... I thought it would be good for once to have a show of force so folks realize MyGeneration is "for real"
|
|
|
|
|
What you're describing sounds almost like Ruby's ActiveRecord. Have you looked at that at all? (Oh...and is all this in the MyXaml package?)
Oh geez... the forum keeps spinning... you'll take care o f it i'm sure, c'ause ... yeah, i neede this. *cough* anyway good job finding the bug. -Shog9 on...a Firefox bug.
|
|
|
|
|
David Stone wrote: Have you looked at that at all?
Yes, in fact, there seems to be a lot of similarities on the surface, but I haven't dug down to look at the details. But the Ruby stuff seems VERY similar.
David Stone wrote: and is all this in the MyXaml package?)
Nooooo. I'm hoping to make this a commercial product. A loooong journey, there.
Marc
Pensieve
Some people believe what the bible says. Literally. At least [with Wikipedia] you have the chance to correct the wiki -- Jörgen Sigvardsson
|
|
|
|
|
Microsoft .Net solutions really don't compare with scripting language solutions - even OOP ones like Ruby. Things must be attacked differently when you don't have a compiler or the powerful intellisense that Visual Studio provides. If I was doing a Ruby project, I wouldn't want strongly typed objects/members at all. I would want a lean, mean, runtime machine.
|
|
|
|
|
I'm fully aware of that. I use LLBLGen for my OR/M layer. I was just remarking on the fact that Marc's framework sounds an awful lot like ActiveRecord.
Oh geez... the forum keeps spinning... you'll take care o f it i'm sure, c'ause ... yeah, i neede this. *cough* anyway good job finding the bug. -Shog9 on...a Firefox bug.
|
|
|
|
|