Vibrant discussion about CSLA .NET and using the framework to build great business applications.
While Craig is right, it is also theoretically possible to create a number of EF mappings for the database to match the shapes of your business objects. You can't do this all in one EF model because EF won't do multiple mappings per entity, so it is a real pain, but it can be done in theory.
I haven't had time to dig deeply into the .NET 4.0 EF implementation, but they were talking about adding some features (either in 4.0 or later) that might make mapping into managed CSLA properties possible.
If those are there, then some auto-mapping might be possible - assuming you get your entity shapes to exactly match the object shapes.
Rocky
cds: I use code generation to map from my CSLA business object classes to my ORM classes so it's not really a problem for me
Luc Morin, T.P. http://www.stlm.ca
There have been complaints in the past that Codesmith templates are too data-centric and that they only let you pull data from one table at a time. I still do this most of the time for the Code Gen level of my BOs and then I hand code the extra fields from other tables. I like having Bos that cleanly map to my tables. I usually encapsulate them inside a higher level BO to handle the use case. I call those Use Case Controller objects (or Unit Of Work - UOW). They do the high level coordination of BOs for the use case. i.e. fetch the Root BO and its children, some Read Only Collections, a few NVLs, etc. Then the screen binds to the Root BO and the extra data is used for dropdowns, etc.
But Codesmith is far more flexible than that. I just don't use a lot of the advanced features. I think some people have defined XML files that Codsmith can read and use to generate BOs.
In some other cases I have designed SQL Server Views (of a many table join) and then pointed Codesmith at the View instead of the table and it spit out a whole BO.
So a lot of this can be overcome with more training and experience with Codesmith.
Joe
JoeFallon1:There have been complaints in the past that Codesmith templates are too data-centric and that they only let you pull data from one table at a time. I still do this most of the time for the Code Gen level of my BOs and then I hand code the extra fields from other tables. I like having Bos that cleanly map to my tables. I usually encapsulate them inside a higher level BO to handle the use case. I call those Use Case Controller objects (or Unit Of Work - UOW). They do the high level coordination of BOs for the use case. i.e. fetch the Root BO and its children, some Read Only Collections, a few NVLs, etc. Then the screen binds to the Root BO and the extra data is used for dropdowns, etc.
How does that work with regards to db transactions when it comes to writing the data back? Is it still possible to get all the writes inside one transaction?
JoeFallon1: In some other cases I have designed SQL Server Views (of a many table join) and then pointed Codesmith at the View instead of the table and it spit out a whole BO.
That's exactly what we've done for the readonly objects in a lot of cases. The only issue we have there is we are using Rocky's approach for refreshing locally held readonly objects when the editable versions change, which works well except where the readonly object has data that the editable version doesn't (e.g. an editable sales order line has the stockId, but the readonly version has the stockItemName say) - in that scenario we need to roundtrip the database to get the stock item name.
For the readwrite objects we keep tripping over the 'views can only write to one table' restriction, so have ended up with sprocs. It's this mix of sprocs and views that nags me, seems messy and like there must be a better way.
JoeFallon1: So a lot of this can be overcome with more training and experience with Codesmith.
That definitely applies to us! It is a great tool and now I have got my head round it's breakpoints and debugging codesmith templates in VS it is all making a bit more sense. Incidentally; we took you're advice and made our templates work for us, rather than just code-genning the first time and never again - it has already saved us days of work when we have needed to re-gen, so thank you for stopping me taking the easy way out!
I take my hat off to those who produced the original cslacontrib templates too... more people on the list of of people I owe a drink.
asp2go:@Tom - Note also that if you are working with a mod version of the CSLA Contrib templates there is a CslaXml file in there that allows you to build your objects by defining the tables/fields/attributes to be included in an Xml file and the object doesn't need to be from a single table. Then the Linq 2 Sql that is generated addresses the various tables.
If you weren't using L2S you could likely leverage the template to build the dal 'your way'.
I'm currently doing exactly what you are working on and looking at potentially building a visual designer that would create that Xml and allow you to more easily create the BO's. The combination of ideas from various tools and templates out there will get us there eventually I think. The Sculpture solution looks very impressive and is the most advanced version I've seen of what we are after here - it's worth looking at but I'm still getting several issues with the beta release bugs.There really are a lot of options - I've looked at Codebreeze, Codesmith's new templates, CodeComplete, CslaGen, CslaContrib and a couple other options lately all of which have great features. In any event I'm going to focus on a custom Xml definition driven approach that is capable of creating behavioral rather than data-centric BOs.
I really have two points – one is a repeat.
Good object models almost never match the database shape. Sure, some objects do. But many important objects won’t match the database shape. Few (if any) ORM tools actually provide the flexibility to map a table (in whole or part) to n different object types. Or to map n different tables (in whole or part) to a single object type. EF doesn’t do this – in fact it can only map a table once as I understand it.
So while it is a great goal for an ORM to do this, after 15+ years of people building ORMs and failing to achieve the goal, I’m not holding my breath…
The second point deals with ObjectFactory and EF. I put ObjectFactory into CSLA .NET in anticipation of EF someday being powerful and flexible enough to instantiate CSLA .NET object graphs. That would make it possible to create an EfObjectFactory that did all the work based on an EF mapping file. For this to work a couple things must be true:
· EF must allow CSLA to instantiate every object (root, collections, child objects, etc) so CSLA can initialize the metastate (IsDirty, IsNew, etc).
· EF must allow CSLA to get/set property values – especially since fewer and fewer objects use private backing fields, and many objects have read-only properties, etc. In other words, EF must allow CSLA to call ReadProperty() and LoadProperty() to get/set the values
It may be the case that EF 4.0 has these capabilities – I haven’t had time to look. Certainly they have improved POCO support, but the question is whether they provide extensibility points for the create an object instance, set a property and get a property operations.
Ultimately I hope these extensibility points do exist, because it should then be possible to create an EfObjectFactory that you simply invoke for an EF query, and you get back a fully populated CSLA object graph as a result.
I should point out though, that there’s virtually zero chance that the EF designer would create your business classes. They might map to classes you write, but their designer is very unlikely to generate CSLA code :) The most you might hope for is that they use T4 templates for all their code-gen, so someone could entirely rewrite all the EF templates to code-gen CSLA output. I don’t think that’s true in EF 4.0 – but maybe it is?