- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Documentation
Joined: 14-Dec-2003
I've several thoughts on how to make the documentation work better for me.
1) In LLBL Gen Pro Documentation, add examples that do more complicated things. For example yesterday I started in on dynamic lists. The sample got me started, but didn't take my far enough. It would be great to have a second, and third example that did more complicated things, filter on fields not in result field, having clauses, agregates with default aliases and so on. The three examples could cover a lot of ground through overlapping concepts.
2) What I really haven't found is a meta document that discusses the concepts of the framework, the terminology used, the relationships between objects.
I've only glanced at the SDK documentation, but it seems to also be detailed, not general.
arschr wrote:
I've several thoughts on how to make the documentation work better for me.
You do know it's already 289 printed pages?
1) In LLBL Gen Pro Documentation, add examples that do more complicated things. For example yesterday I started in on dynamic lists. The sample got me started, but didn't take my far enough. It would be great to have a second, and third example that did more complicated things, filter on fields not in result field, having clauses, agregates with default aliases and so on. The three examples could cover a lot of ground through overlapping concepts.
The one thing people ask me is to provide more simpler examples What I find interesting about your question is that you mention the example of the dynamic list. The example I mentioned for dynamic list, i.e.: the multi-join aliasing example, is often found to be 'too complex' and not understandable. The "How do I use a group by clause in a dynamic list ?" how do I question does IMHO contain everything you want.
2) What I really haven't found is a meta document that discusses the concepts of the framework, the terminology used, the relationships between objects.
I've only glanced at the SDK documentation, but it seems to also be detailed, not general.
There's a whole 'concepts' section in the documentation which discusses the concepts used for the code. I won't ship a functional research document for the code with the framework if you ask for that, though if you first read the concepts section, then if you want to know more, read the template group descriptions in the SDK (last 2 options in the Templatesets section) docs, you have a proper overview. Though the complete system is 2 fold: 1) the designer/project meta data / taskperformers/templatesets and 2) generated code and runtime library.
What kind of depth did you expect? It explains the philosophy behind why the framework is the way it is. It's THERE because I wanted people to understand that philosophy.
Joined: 14-Dec-2003
Yes, It's fine for exposing people to the philosophy. Another level might be how you've decided to express the philoshopy in llblgen pro.
You've build the system from a set of building blocks, Entities, relationships, predicate expressions, prefetch paths, lazy loading, typed lists, fields etc. A discussion of what each is and how it relates to the others. For example columns in a table get used in many of the components, are there different ways to reference fields and agregates of fields, depending on the construct, (Entity, typed list, predicate expression, sort expression etc) or is there a common field thing that is being used instead.
Another example might be when do you use a factory to construct on object and when do you use it's constructor I now have thers two lines next to one another
whereclause.Add(new FieldCompareValuePredicate(fields[3], null, ComparisonOperator.Equal, "Pending"));
whereclause.Add(PredicateFactory.CompareValue(CustomersFieldIndex.Active, ComparisonOperator.Equal, "Y","Customers"));
They must be basically equivelant, how do I do the same thing with one vs the other and why.
As you answer questions on the forum you must see many common threads, assuming people are trying to use the documentation before they ask a question (and I know some aren't). Each message begats the documetation question of how could I have answered this in the documentaion, because for each person who asks the question there are more who have it who aren't asking it.
Thanks for your feedback, I really appreciate it (and you obviously care, otherwise you wouldn't have bothered ).
Ok, I'll try to address your concerns below.
arschr wrote:
Yes, It's fine for exposing people to the philosophy. Another level might be how you've decided to express the philoshopy in llblgen pro.
The reason the philosophy is described is because LLBLGen Pro doesn't use the 'normal' O/R mapping 'start with a class' oriented approach, so the explanation why LLBLGen Pro works the way it works is there to make sure the user understands it works from the relational model upwards.
You've build the system from a set of building blocks, Entities, relationships, predicate expressions, prefetch paths, lazy loading, typed lists, fields etc. A discussion of what each is and how it relates to the others. For example columns in a table get used in many of the components, are there different ways to reference fields and agregates of fields, depending on the construct, (Entity, typed list, predicate expression, sort expression etc) or is there a common field thing that is being used instead.
'Entity' has 'Field' (one or more). That concept is the cornerstone. Everything else is technical detail. The point is that whenever an entity field is used, the developer has to specify an EntityField(2) object. As a shortcut, you can, when possible, also use the field index, which under the hood is used to produce an entity field object.
The confusion starts when the developer is confronted with the fact that there are more ways to do the same thing. For example your next example:
Another example might be when do you use a factory to construct on object and when do you use it's constructor I now have thers two lines next to one another
whereclause.Add(new FieldCompareValuePredicate(fields[3], null, ComparisonOperator.Equal, "Pending")); whereclause.Add(PredicateFactory.CompareValue(CustomersFieldIndex.Active, ComparisonOperator.Equal, "Y","Customers"));
They must be basically equivelant, how do I do the same thing with one vs the other and why.
You can produce predicate objects in a couple of ways: via the constructors on the classes, or using the predicatefactory shortcuts. In 'Filtering and Sorting, 'The predicate classes'', the following text is specified: Each predicate class is described below, its usage and if it is included in the PredicateFactory helper class for easy predicate fabrication. The PredicateFactory class is a generated class and is located in the FactoryClasses namespace in the database generic project in the generated code. All predicate classes are described using their real class name, and the shortcut (if available) for the PredicateFactory is specified as well, with an example.
So if there's confusion about if they're different things: predicatefactory.CompareValue or new FieldCompareValuePredicate(..), it is explained. Though as I said earlier on: the documentation is massive, it's a complete book, and I'm pretty sure not everyone reads everything and even if you do, you forget details. Even I have to consult the docs / ref manual often when answering questions, just because I don't know every detail anymore. I use that also as a check to see if I can indeed find the answer back in the provided docs or not. (i.e.: if I have to check code, there is a lack of docs in that area).
I'm also pretty sure a lot can be improved in the docs still, especially in the area where the transformation between concept and implementation/technical detail is made. Sometimes a user has problems in that area. The main cause I've learned is that these people often still think in pure SQL and get stuck to convert that back to predicate objects.
As you answer questions on the forum you must see many common threads, assuming people are trying to use the documentation before they ask a question (and I know some aren't). Each message begats the documetation question of how could I have answered this in the documentaion, because for each person who asks the question there are more who have it who aren't asking it.
True, however the vast majority of the questions are about things which are documented, but the user either makes the wrong connections between the things described or is stuck in a way of working with data which is different from how LLBLGen pro threats data, e.g. "how to write this query with predicates?". The core problem most people have is how to write a particular filter/query with predicates.
The main solution is IMHO that the people who have problems grasping filtering, have to step away from SQL and start thinking in entities and a set of entities and how to retrieve a subset from them using a filter. That takes time, and no matter how many SQL-to-predicate examples I put up, the transition isn't made easier with that (probably only harder).
Though the way predicate objects have to be used in C#/VB.NET now isn't helping, I'm the first to admit that. Some people really like it, others hate it. It already helps if you explain to them that 'A.B=10' in SELECT * FROM A WHERE A.B=10 is a predicate. And thus building up a set of predicates is in fact the same as formulating it in SQL, though it can be a struggle if that connection isn't made.
I've to say: sometimes I wished a person had tried more before asking here (so the person learns more), and sometimes I really wished the person would have asked earlier (so the person isn't frustrated after a couple of hours of trying). I don't mind pointing people to pages in the manual where the solution is described.
Also, the reference manual isn't something useless either, it contains a lot of information about technical details of classes.