- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
LLBLGen Datasource and errors
Joined: 07-Apr-2008
I'm currently evaluating LLBLGen Pro in the demo version, and it looks promosing, although i only understand a small part of what it is doing.
I'm investigating the best practice with using a LLBGendatasource in our asp.net sites. I created a SelfServicing project from our relational database, but i'm still breaking my head over some issues, maybe someone can shed some light on it:
-
How to deal with more resultsets from more than one table (e.g. users, roles and userroles) and still be able to use the build-in CRUD features of the GUI data controls like gridviews etc. in combination with the LLBLGenDataSource without much additional code?
-
How to deal with exceptions in the generated code? They just don't bubble up to my presentation layer. For example i get this Unique Key Constraint Violation runtime error (ORMQueryeexecutionException), but i want the generated-code layer to check for the constraints in disconnected mode, and report that back to the presentation layer to handle, instead of executing to database and throwing such an exception.
-
I'm a little worried about doing redundant work and resource intensitivity. Is every data-object that the generated code creates disposed, every time i have a page cycle? How about multi-user environments, are entitycolelctions shared between them? What configuration changes can i / should i make to have control over this behaviour and if so, what is best practice?
I know, it is a pretty vague set of questions, but i'm just trying to figure out how llblgen can be our way to go, in stead of using the typed-dataset buildin features of vs2005.
Thanks a lot for any answers!
Joined: 08-Apr-2008
Hi!
My view of LLBLGen Pro is a tool that generates source code, instead of getting a programmer to type up the code. This helps cut development time and reduces errors too, since everything is based on tested templates (the downside is the learning curve of using the classes, but that's just the first time you use LLBLGen Pro).
To address your concerns:
-
You can create entities based on views, just as you would create entities based on tables. This enables you to work with results obtained from multiple tables.
-
I'm not sure of how you would get the presentation layer to handle errors without using exceptions (perhaps you would use return types instead?). IMHO, the presentation layer gets its notifications through exceptions - the exception object encapsulates a message string that the U.I. can display to a user.
-
The entity objects and collections are normally disposed between page cycles. ASP.NET allows you to store application-level and session-level variables and also provides you with a caching mechanism. You could also use a 3rd party cache for this purpose.
Hope this helps.
Regards, NiTiN
Joined: 07-Apr-2008
Thank you for your comments. I think i was not clear enough though.
1. What i ment by complicated queries, is especially dealing with the update-routines. e.g. with Dataset.xsd i can define different Stored procedures for every CRUD action. As far as i can see now with llblgen i have to use 1 entitycollection, which has autogenerated CRUD commands.
2. That is exactly the problem. The Exception is thrown in the generated code. I get runtime error, i do not know where / how to catch these errors when using a llblgendatasource. They just don't bubble up to the layer where i can handle them.
3. I'm aware of the caching mechanisms and session vars, only, with llblgen kind-of shielding the objects from me, i'm not sure what exactly to cache. For instance, i have this page where a complete userlist is requested. I do this with the LLBLGenDataSource attached to a gridview, nothing fancy. I use paging, pagesize=25, nr of users in this table is about 2000. Number of concurrent users on this site is 10. What should i cache? Is the llblgendatasource intelligently sharing objects between different sessions? And what about paging? Does llblgen request a subset from the database, or is the entire table requested every single time, and only a subset displayed in the gridview?
1. What i ment by complicated queries, is especially dealing with the update-routines. e.g. with Dataset.xsd i can define different Stored procedures for every CRUD action. As far as i can see now with llblgen i have to use 1 entitycollection, which has autogenerated CRUD commands.
If you want to perform multiple actions in a batch, please check the Unit of Work. (manual: Using the generated code -> Adapter/SelfServicing -> Unit of work and field data versioning)
2. That is exactly the problem. The Exception is thrown in the generated code. I get runtime error, i do not know where / how to catch these errors when using a llblgendatasource. They just don't bubble up to the layer where i can handle them
Please check the following thread: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=8021
Is the llblgendatasource intelligently sharing objects between different sessions?
It doesn't share them between sessions, you should take care of this using an Application variable. You may also find the following thread useful: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=13028
And what about paging? Does llblgen request a subset from the database, or is the entire table requested every single time, and only a subset displayed in the gridview?
If you enable Paging on the LLBLGenProDataSource, it will only fetch the required page from the database. Otherwise if paging was disabled on the LLBLGenProDataSource the the entire table would be fetched each time, and the databound control takes care of displaying the required page.
Joined: 07-Apr-2008
Okay thanx!
One thing about paging though:
I discovered that the LlblGenDataSource.EntityCollection.Count represents the total amount of records in the table (no matter what pagesize is selected in the bound gridview) Only after the first page-change (clicking another page in the pagerrow of the gridview) the llblgendatasource.entitycollection.count is the number of records on one page.
Why is this? It looks like the datasource does collect all the records the first time. I was kindof depending on this, and wrote my search-function against the entitycollection of the datasource, to get a index for a searched record, but found out that the search is limited to the visible records only after a page change. This seems inconsistent.
For the search function, i will use an new instance of the EntityCollection to solve for now, but i do not think this behaviour is by design.
What am i doing wrong?
And in addition to this:
What is the best way to solve this problem: I have a llblgendatasource called UsersDataSource , which is reading a entitycollection type named TUsersCollection (the users table from the database) I bound a gridview called UserGridView to it, which uses paging.
No i have a search function, which wil take the text from the search-textbox, and have to perform a search with the LIKE parameter on two fields. When a search is performed and a user is found, i want to select this row in the gridview, even is the record is not currently displayed (because of being on another page). Now, when using the datasource.EntityCollection class, this breaks, because of the explanation above. I don't feel like having to create a new TUserCollection every single search with ALL the records, just to be able to get the rowindex to select in a grid. There MUST be a better way to accomplish this task. Can anyone help me please?
Here a code sample to clear some things up. It's a bit simplified, this is the one searching by userid:
In my classes:
public static void SetGridToIndexByUserID(GridView gv, TUserCollection users, int userid)
{
List<int> i;
i = users.FindMatches(new PredicateExpression(new FieldCompareValuePredicate(TUserFields.UserId, ComparisonOperator.Equal, userid)));
if (i.Count > 0)
{
if (gv.AllowPaging)
{
gv.PageIndex = i[0] / gv.PageSize;
gv.SelectedIndex = i[0] % gv.PageSize;
}
else
{
gv.SelectedIndex = i[0];
}
}
else
{
gv.SelectedIndex = -1;
}
}
And in my aspx file:
Logic.BusinessLogic.Users.SetGridToIndexByUserID(UserGridView, (TUserCollection)UsersDataSource.EntityCollection, int.Parse(UserIDSearch.Text));
I discovered that the LlblGenDataSource.EntityCollection.Count represents the total amount of records in the table (no matter what pagesize is selected in the bound gridview) Only after the first page-change (clicking another page in the pagerrow of the gridview) the llblgendatasource.entitycollection.count is the number of records on one page.
Which LLBLGenPro runtime library are you using?
What is the best way to solve this problem: I have a llblgendatasource called UsersDataSource , which is reading a entitycollection type named TUsersCollection (the users table from the database) I bound a gridview called UserGridView to it, which uses paging.
No i have a search function, which wil take the text from the search-textbox, and have to perform a search with the LIKE parameter on two fields. When a search is performed and a user is found, i want to select this row in the gridview, even is the record is not currently displayed (because of being on another page).
You can't do this when you are enabling paging in the datasource, what you can do then is to use the datasource FilterToUse property to fetch this user alone. This way you would end up having one page with the specified user.
And if the user want to clear the search you should in turn clear the FilterToUse property.
Joined: 07-Apr-2008
Wow thanx! That works like a charm!
The only thing is, when i try to extend the FilterToUse, it is not working, but i might be overseeing something.
Situation: The first postback: The user has typed a search-text in the textbox and i add 1 fieldlikepredicate to the filter with AddWithOr method.
The grid refreshes and shows the filtered data.
Again, the user wants to add another search term to narrow down the search, so on the next postback i simply do the same thing: AddWithOr, another fieldlikepredicate. This does not seem to work and the grid only shows the first filtered result, lthough the FilterToUse.count is incremented.
This should work right?
Joined: 07-Apr-2008
code from the codebehind file:
protected void SearchUserButton_Click(object sender, EventArgs e)
{
FilterUserDataSource(UsersDataSource, SearchUserTextBox.Text);
}
code from other class:
public void FilterUserDataSource(LLBLGenProDataSource DS, String Text)
{
if (DS.FilterToUse == null)
{
DS.FilterToUse = new PredicateExpression();
}
DS.FilterToUse.AddWithOr(new FieldLikePredicate(TUserFields.UserName, "%" + Text + "%"));
DS.FilterToUse.AddWithOr(new FieldLikePredicate(TUserFields.FullName, "%" + Text + "%"));
Debug.Print (DS.FilterToUse.Count.ToString());
}
The first time the SearchUSerButton is pressed, the text from the UserSearchtextBox is added to the filter, the count is then 3 (i don't know why not 2?) The gridview gives the right result
The second time, another text is added, the count becomes 7 strangly enough... The gridview however is still displaying the first filtered result...
Also the Perform_Select event is never fired in the second case.
Please try the following:
protected void SearchUserButton_Click(object sender, EventArgs e)
{
FilterUserDataSource(UsersDataSource, SearchUserTextBox.Text);
gridView.Databind();
}
public void FilterUserDataSource(LLBLGenProDataSource DS, String Text)
{
if (DS.FilterToUse == null)
{
DS.FilterToUse = new PredicateExpression();
}
DS.FilterToUse.AddWithOr(new FieldLikePredicate(TUserFields.UserName, "%" + Text + "%"));
DS.FilterToUse.AddWithOr(new FieldLikePredicate(TUserFields.FullName, "%" + Text + "%"));
DS.Refetch = true;
Debug.Print (DS.FilterToUse.Count.ToString());
}
Joined: 07-Apr-2008
As in my other thread, i discovered i'm failing (must be the almost-weekend thing )
I keep adding the filters as AddWithOr, so either one or the other ... the resultset is correct this way.
What i NEEDED to do was: add the two filters with or, but add any new filter with and! Because i want to narrow down the search...
This is what the code should look like:
public void FilterUserDataSource(LLBLGenProDataSource DS, String Text)
{
if (DS.FilterToUse == null)
{
DS.FilterToUse = new PredicateExpression();
}
PredicateExpression filter = new PredicateExpression();
filter.AddWithOr(new FieldLikePredicate(TUserFields.UserName, "%" + Text + "%"));
filter.AddWithOr(new FieldLikePredicate(TUserFields.FullName, "%" + Text + "%"));
DS.FilterToUse.AddWithAnd(filter);
}
I'm sorry to have wasted your time !