- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Getting started: simple JOIN
Joined: 11-Jan-2005
Hi,
I'm just getting started with LLBLGen (yay!), but am having some trouble finding the "easiest" way of doing things. Have read through the .chm file help docs, and fished through the forum for some "getting started" examples (alas, didn't find many or didn't look in the right place... anyone have some gettings started docs other than the help docs?)......
Anyway, I am using Adapter and have this simple SQL query and am trying to figure out the easiest way to get the data I want, ideally only the columns I need and preferably without making a typed list or typed view in the designer (because I anticipate this kind of need popping up once in a while and don't necessarily want to go back to the designer to do it, would rather know a short way to do it in code)....
Here's the query:
select u.FirstName, u.LastName, u.UserID from Users u inner join UserSponsorMap usm on u.UserID = usm.UserID where usm.SponsorID = @SponsorID order by u.LastName, u.FirstName
Any insight would be appreciated. FWIW, the results will then be bound to a DropDownList control, using UserID as the key and "LastName, FirstName" as the value.
Thx, Jack
There is a section called 'How Do I?' in the best practises section, perhaps you've missed it , with a list of things new users run into a lot and how to solve them.
You clearly want to construct a dynamic list. This is documented here: using the generated code -> Adapter -> Using the typed list and typed view classes -> Creating a dynamic list.
Now, the example there is perhaps a bit complex (but no-one needs really obvious examples ) so in your case, your query is something like:
ResultsetFields fields = new ResultsetFields(3);
fields.DefineField(UserFieldIndex.FirstName, 0, "FirstName");
fields.DefineField(UserFieldIndex.LastName, 1, "LastName");
fields.DefineField(UserFieldIndex.UserId, 2, "UserID");
IRelationPredicateBucket bucket = new RelationPredicateBucket();
bucket.Relations.Add(UserEntity.Relations.UserSponsorEntityUsingUserId);
bucket.PredicateExpression.Add(
PredicateFactory.CompareValue(UserSponsorFieldIndex.SponsorID,
ComparisonOperator.Equal, mySponsorID));
SortExpression sorter = new SortExpression(
new SortClause(fields[1], SortOperator.Ascending));
sorter.Add(new SortClause(fields[0], SortOperator.Ascending));
DataTable dynamicList = new DataTable();
DataAccessAdapter adapter = new DataAccessAdapter();
adapter.FetchTypedList(fields, dynamicList, bucket, 0, sorter, true);
Otis wrote:
There is a section called 'How Do I?' in the best practises section, perhaps you've missed it
, with a list of things new users run into a lot and how to solve them.
Frans when I was starting out... The "How Do I" section eluded me also... Maybe you should put a reference to it on the Getting Started page. Dooh I just checked and there is a reference.
The other thing about "How Do I" is that it is very difficult to read the list at a glance. Maybe if the "How do I" text was removed from each bullet line it might make it easier to find what you are looking for in the list.
Joined: 11-Jan-2005
Hi,
Thanks for the quick feedback, much appreciated. I did look at the How Do I section, but didn't see an example there that seemed to match my needs. I just looked again and frankly still don't see which one would have given me the answer that I needed.
I pulled down a copy of LLBLGen last week, after much comparison with other offerings. It looked like one of the more robust ones out there, and able to handle complex joins, complex predicates, multi-column PK's, cross-table "types" (typed list, typed view)... blah blah... many things going for it. The docs even looked better than a lot of the other product's docs... some of which are pretty much just class diagrams with comments.
Anyway, I've found that getting up to speed is taking longer than I expected. I'm in the process of creating a new, somewhat large system and LLBLGen should save me a lot of time. Some code is already written, as are SP's, most/all of which I would like to replace with LLBLGen calls. So, getting up to speed for me is two-fold: learning the basics and converting existing DAL stuff.
What would be really helpful would be more concrete examples of how to do things. The Help file jumps pretty much from "real basic" (get an entity) to "and here's how to use nested predicates". I need to extrapolate what's in between (for average uses) and (this is the tough part for getting up to speed), figure out the most straightforward way to do what I want to do. Right now it's "maybe I could do it this way, or this way, or this way, or, hmm, scratching head".
That's the way it often is learning new products, so I'm not makin a stink, but my suggestion is to maybe have more concrete examples of how to do a range of things AND equate them back to the SQL that they would be replacing. I'm guessing that most new users have years of writing SQL statements under their belt, so something like:
If you're SQL would be something like this:
select blah blah blah from blah inner join blah left join blah where blah blah
Do something like this in LLBLGen:
blah blah blah
That would also help in the leap that's required to come to terms with the terminology that LLBLGen uses to describe itself (Entities, buckets, predicates, etc, etc).
Another thing that I would find helpful (and maybe this is in the docs, but I didn't see it) would be to somehow tell me how the naming works for the entity object model. IE, "if you create a UserEntity, you will be also get a UserEntityCollection, will be able to user UserFieldIndex (or whatever the right terms are), etc. IE, something that tells me exactly what I have available to me for each entity after it's generated. (maybe something that simply documents the objects/properties that can be created/used).
Thx, Jack
Joined: 11-Jan-2005
BTW, Frans, the code you supplied above worked pretty much as is, thx. I do have a problem with the sort part, though. The fields[0] and fields[1] parts of the SortClause cause this error:
The argument type SD.LLBLGen.Pro.ORMSupportClasses.IEntityField2 is not assignable to parameter type SD.LLBLGen.Pro.ORMSupportClasses.IEntityField.
I have a reference in my project for SD.LLBLGen.Pro.ORMSupportClasses.NET11, am using .NET 1.1 in VS.NET 2003 IDE, generated the code using the Adapter full/safe VS.NET 2003 (1.0.2004.1.061404) generator config and have this using in the cs file:
using SD.LLBLGen.Pro.ORMSupportClasses;
Thx, Jack
oops, I used the selfservicing constructor. Add a null for the persistence info in the adapter constructor (so add a ,null after the field specification). I'll address your other posting first thing tomorrow
Jackk100 wrote:
Thanks for the quick feedback, much appreciated. I did look at the How Do I section, but didn't see an example there that seemed to match my needs. I just looked again and frankly still don't see which one would have given me the answer that I needed.
The How Do I section lacks examples for the more advanced features. This will be addressed soon. Sorry for that. In the meantime, don't hesitate to ask here, and I'll give you an example. Also the search can give you various examples already posted on the forums
I pulled down a copy of LLBLGen last week, after much comparison with other offerings. It looked like one of the more robust ones out there, and able to handle complex joins, complex predicates, multi-column PK's, cross-table "types" (typed list, typed view)... blah blah... many things going for it. The docs even looked better than a lot of the other product's docs... some of which are pretty much just class diagrams with comments.
Yeah, often 'reference' docs is all you get. Still the docs can be better, and we try to do that in every revision, it's still a gamble if an explanation of a feature is enough or that it requires extensive examples in various steps.
Anyway, I've found that getting up to speed is taking longer than I expected. I'm in the process of creating a new, somewhat large system and LLBLGen should save me a lot of time. Some code is already written, as are SP's, most/all of which I would like to replace with LLBLGen calls. So, getting up to speed for me is two-fold: learning the basics and converting existing DAL stuff.
What would be really helpful would be more concrete examples of how to do things. The Help file jumps pretty much from "real basic" (get an entity) to "and here's how to use nested predicates". I need to extrapolate what's in between (for average uses) and (this is the tough part for getting up to speed), figure out the most straightforward way to do what I want to do. Right now it's "maybe I could do it this way, or this way, or this way, or, hmm, scratching head".
Well, there are often multiple paths to do the same thing, this is done to allow developers keep on developing software the way they want to. For example, you can fetch a collection of entities using GetMulti(filter), but you can also fetch a collection by using GetMulti(relatedEntityInstance...) etc. Furthermore, did you check out the Northwind example apps? They contain some examples of how to use the functionality build in, like scalar functions, aggregates, prefetch paths, lazy loading (the selfservicing version), databinding etc.
That's the way it often is learning new products, so I'm not makin a stink, but my suggestion is to maybe have more concrete examples of how to do a range of things AND equate them back to the SQL that they would be replacing. I'm guessing that most new users have years of writing SQL statements under their belt, so something like:
If you're SQL would be something like this:
select blah blah blah from blah inner join blah left join blah where blah blah
Do something like this in LLBLGen:
blah blah blah
That would also help in the leap that's required to come to terms with the terminology that LLBLGen uses to describe itself (Entities, buckets, predicates, etc, etc).
I tried to do that with the filtering & sorting docs where I illustrated the filter predicates with equal sql statements. The problem is though: filtering on an object set is not SQL and never will. People often fall into the trap of starting with an extensive query in SQL and then wonder "How am I going to convert this into these predicate thingies?". This is the wrong approach. You should be thinking: I want this subset of the total amount of data of a given type (entity, or set of related entities), and I can use this construct to get all that data, but as I want a subset, I need a filter to limit my subset. ", which means: create the filter and go.
Another thing that I would find helpful (and maybe this is in the docs, but I didn't see it) would be to somehow tell me how the naming works for the entity object model. IE, "if you create a UserEntity, you will be also get a UserEntityCollection, will be able to user UserFieldIndex (or whatever the right terms are), etc. IE, something that tells me exactly what I have available to me for each entity after it's generated. (maybe something that simply documents the objects/properties that can be created/used).
The reference manual which contains generated code for an example DAL on adapter and selfservicing, contains material for this, but in general, the documentation is focussed on explaining the functionality from the "I want to do this" perspective even though this might not be obvious at first. The problem is with trying to explain everything that the documentation will become very large and dull and no-one will read it as the functionality offered is big and the number of different ways to use it is huge. Still, in the end, the amount of questions the developer asks is relatively small: I want this data and that data, how to do that? I want to retrieve just that column and that aggregate how to do that? Can I filter on this and sort on that? etc. These questions arise from the functional perspective: they have to fill a combo box with a given amount of data and wonder how to get that data. Instead of thinking in SQL, it's then wise to start from the complete set of objects and limit the set you want to retrieve with a filter. That's mainly the core issue.
Joined: 11-Jan-2005
Furthermore, did you check out the Northwind example apps? They contain some examples of how to use the functionality build in, like scalar functions, aggregates, prefetch paths, lazy loading (the selfservicing version), databinding etc.
No, I didn't, will do, thx.
I tried to do that with the filtering & sorting docs where I illustrated the filter predicates with equal sql statements. The problem is though: filtering on an object set is not SQL and never will. People often fall into the trap of starting with an extensive query in SQL and then wonder "How am I going to convert this into these predicate thingies?". This is the wrong approach. You should be thinking: I want this subset of the total amount of data of a given type (entity, or set of related entities), and I can use this construct to get all that data, but as I want a subset, I need a filter to limit my subset. ", which means: create the filter and go.
Whether it's the right or wrong approach, it's the approach I took, and since I've been working with SQL for 12+ years, it's logical that I would do that. My guess is that lots of other people do the same thing, since SQL is already a solid foundation for them... they want to know how LLBLGen is going to replace all those years of writing/creating the SQL that they already understand.
I would also guess that you probably lose potential customers who know SQL really well and can't muster the patience or time for the learning curve. Having more concrete examples will help, or at least would help me. I can dig through the forums (and have been), but that's not as easy as seeing examples in the docs.... though I gotta look at the Northwind, not sure why I didn't yet. Anyway, my 2c.
The problem is with trying to explain everything that the documentation will become very large and dull and no-one will read it as the functionality offered is big and the number of different ways to use it is huge.
I recently bought a product from ComponentArt.com. Their docs are an example of what I think a good help doc is about. As are the ones from quiksoft.com. Dull, maybe for someone who already understands the concepts, but well organized, which can make up for being dull, because as long as you can zero in on what you need, the rest of the dull stuff isn't in the way.
Thx, Jack
Jackk100 wrote:
I tried to do that with the filtering & sorting docs where I illustrated the filter predicates with equal sql statements. The problem is though: filtering on an object set is not SQL and never will. People often fall into the trap of starting with an extensive query in SQL and then wonder 'How am I going to convert this into these predicate thingies?'. This is the wrong approach. You should be thinking: I want this subset of the total amount of data of a given type (entity, or set of related entities), and I can use this construct to get all that data, but as I want a subset, I need a filter to limit my subset. ', which means: create the filter and go.
Whether it's the right or wrong approach, it's the approach I took, and since I've been working with SQL for 12+ years, it's logical that I would do that. My guess is that lots of other people do the same thing, since SQL is already a solid foundation for them... they want to know how LLBLGen is going to replace all those years of writing/creating the SQL that they already understand.
understood, but the transition won't be easy. It's another way of thinking: get me objects and I'll specify the filter which defines which ones. SQL is thinking in sets and how to manipulate them to get a new set of fields and data.
Similar to thinking in dynamic resultsets won't bring you very far in data as objects. 100 examples won't help in that case, the developer has to make the transition in thinking, which can be swift or very cumbersome, depending on the developer and the developer's experience. But I hear you, I'll try to add more 'this SQL should be written as this' examples, to illustrate some things, but it will never be enough for some while way too much for others (generally speaking).
I would also guess that you probably lose potential customers who know SQL really well and can't muster the patience or time for the learning curve. Having more concrete examples will help, or at least would help me. I can dig through the forums (and have been), but that's not as easy as seeing examples in the docs.... though I gotta look at the Northwind, not sure why I didn't yet. Anyway, my 2c.
What I wonder though is: I tried to explain every element of functionality with an example in the docs, weren't these illustrative enough or too complex? (to give me a better picture of how different users look at the documentation) What I tried was not 'teaching by example', which I personally hate because you'll then teach tricks, not the theory behind it so in a different situation the developer can't project the example on teh actual situation and can't solve the problem, but I was trying to explain the theory behind the functionality so the developer would understand its purpose and the reason why it's there so when the developer needs it, it knows what it does and can use it in a practice.
I don't have any illusions about the learning curve: it's steep, no matter what I do. This is because there is a lot of functionality, so you can't learn everything over night, that takes time. As O/R mapping technology is new to the vast majority of .NET developers, it's not only the tool's aspects but also the technology behind it the developer has to learn. Some developers pick it up rather fast because they don't have a lot of experience with SQL but a lot with OO techniques. Others have more problems and to address these I'm very grateful users are willing to spend some time to explain what's wrong with the docs at the moment (or where improvements can be made ).
The problem is with trying to explain everything that the documentation will become very large and dull and no-one will read it as the functionality offered is big and the number of different ways to use it is huge.
I recently bought a product from ComponentArt.com. Their docs are an example of what I think a good help doc is about. As are the ones from quiksoft.com. Dull, maybe for someone who already understands the concepts, but well organized, which can make up for being dull, because as long as you can zero in on what you need, the rest of the dull stuff isn't in the way.
I don't have experience with these two companies' products so I can't look up what they have, but I'd like to thank you for your feedback and I'll address the documentation with more SQL -> llblgen pro filtering documentation, so people with the experience you have are more able to get started and be productive.
Joined: 11-Jan-2005
Just noticed that the ComponentArt docs won an award:
http://www.componentart.com/whatsNew.aspx#news23
Docs are here, perhaps worth a look:
http://www.componentart.com/Library/default.aspx?content=WebUI_Welcome.htm
- Jack