- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
2-Way Databinding with RadGrid and LivePersistence=False
Joined: 28-Mar-2006
I have been reviewing the forum posts today about "LlblGenProDataSource" and "LiverPersistence" and I have most of my test app working.
I have one question that is causing some issues:
- What is the purpose of the "caching" of the LlblGenProDataSource?
When I set it "Session" it always calls the "PerformSelect" event on each PostBack which then re-fills the datasource again.
My settings are as follows:
First the DataSource:
oGridDs = New LLBLGenProDataSource()
With oGridDs
.ID = "GridDS"
.LivePersistence = False
.CacheLocation = DataSourceCacheLocation.Session
.DataContainerType = DataSourceDataContainerType.EntityCollection
.EntityCollection = New OrderCollection()
With .SelectParameters
logger.Trace("DropDownList.SelectedValue = '{0}'", Me.oDropDownList.SelectedValue)
Dim oCParam As New ControlParameter("CustomerId", "DropDownList1", "SelectedValue")
oCParam.DefaultValue = "ALFKI"
.Add(oCParam)
End With
With .UnitOfWorkObject
End With
End With
Me.phMain.Controls.Add(oGridDs)
Then the Grid:
oRadGrid = New RadGrid()
With oRadGrid
.ID = "RadGrid1"
.DataSourceID = "GridDS"
'.DataSource = Me.oGridDs
.AllowAutomaticUpdates = True
With .MasterTableView
'.DataSourceID = "GridDS"
.AutoGenerateColumns = False
.DataKeyNames() = New String() {"OrderId"}
.AllowPaging = True
.PageSize = 3
With .EditFormSettings
With .EditColumn
.UniqueName = "EditCommandColumn"
.InsertImageUrl = "~/RadControls/Grid/Skins/Default/Insert.gif"
.CancelImageUrl = "~/RadControls/Grid/Skins/Default/Cancel.gif"
.UpdateImageUrl = "~/RadControls/Grid/Skins/Default/Update.gif"
End With
End With
With .Columns
Dim oCol As New GridEditCommandColumn
oCol.ButtonType = GridButtonColumnType.LinkButton
.Add(oCol)
'Dim oTCol As New TemplateColumn
'With oTCol
'End With
.Add(CreateGridBoundColumn("OrderId", GetType(System.Int32), False))
.Add(CreateGridBoundColumn("CustomerId", GetType(System.Int32), False))
.Add(CreateGridBoundColumn("EmployeeId", GetType(System.Int32), False))
'.Add(CreateGridDropDownColumn("EmployeeId", "EmpDropDownDS", "LastName", "EmployeeID"))
.Add(CreateGridBoundColumn("OrderDate", GetType(System.DateTime), False))
.Add(CreateGridBoundColumn("RequiredDate", GetType(System.DateTime), False))
.Add(CreateGridBoundColumn("ShippedDate", GetType(System.DateTime), False))
'.Add(CreateGridBoundColumn("ShipVia", GetType(System.String), True))
.Add(CreateGridDropDownColumn("ShipVia", GetType(System.Int32), "ShipDropDownDS2", "CompanyName", "ShipperID"))
.Add(CreateGridBoundColumn("Freight", GetType(System.String), False))
.Add(CreateGridBoundColumn("ShipName", GetType(System.String), False))
.Add(CreateGridBoundColumn("ShipAddress", GetType(System.String), False))
.Add(CreateGridBoundColumn("ShipCity", GetType(System.String), False))
.Add(CreateGridBoundColumn("ShipRegion", GetType(System.String), False))
.Add(CreateGridBoundColumn("ShipPostalCode", GetType(System.String), False))
.Add(CreateGridBoundColumn("ShipCountry", GetType(System.String), False))
End With
End With
End With
Me.phMain.Controls.Add(oRadGrid)
I am trying to do the following: * When the user "clicks" Edit I want it to display the "editable form" - this works * When the user clicks "Update" on the form, I want it to post-back and fire the PerformWork event - this works * When the form displays again (after the postback from the "update" click) I want the "grid" that is displayed to reflect the changes the user just made - This does NOT work (it always displays the original "grid")
I am certain that if I just save the "collection" on my own, and assign it in the "PerformSelect" it will work just fine - but then my original question comes to mind: What is the purpose of the "caching" if I'm just going to have to cache it anyway? I was assuming that if the data didn't change it wouldn't fire the "PerformSelect" - but it does. I have looked thru the docs and can't find any explanation as to when the caching is used and when it is not. I was wondering if perhaps it is only used when LivePersistence = True - but just don't know.
Thanks for any help.
Andrew.
Joined: 15-Jul-2005
Have you read the documentation section "Generated code - Databinding with ASP.NET 2.0, SelfServicing"? It answers most of your questions I think.
ADF1969 wrote:
- What is the purpose of the "caching" of the LlblGenProDataSource?
It caches data between postbacks.
ADF1969 wrote:
When I set it "Session" it always calls the "PerformSelect" event on each PostBack which then re-fills the datasource again.
You have "LivePersistence=false". If you don't want to raise these events and you want the control to do the updates for you then set it to true.
BTW I'm not sure why you are setting all the values for the control in code. It's really meant to be a declarative control that prevents the need for writing custom code.
ADF1969 wrote:
- When the form displays again (after the postback from the "update" click) I want the "grid" that is displayed to reflect the changes the user just made - This does NOT work (it always displays the original "grid")
Set the Refetch property to True.
Joined: 28-Mar-2006
Chester wrote:
Have you read the documentation section "Generated code - Databinding with ASP.NET 2.0, SelfServicing"? It answers most of your questions I think.
Yes, numerous times. none of my questions are answered there; if they were, I would not be asking them
Chester wrote:
It caches data between postbacks.
Not for me it doesn't. As I stated, it calls the "PerformSelect" EVERY TIME on each "postback" and the "data source" has nothing in it when the page posts back. Which is why I asked the question.
Chester wrote:
You have "LivePersistence=false". If you don't want to raise these events and you want the control to do the updates for you then set it to true.
BTW I'm not sure why you are setting all the values for the control in code. It's really meant to be a declarative control that prevents the need for writing custom code.
I posted "what I want"; I want the events raised - I don't want it to update the database real-time; I want all the "updates" to go into the 'UnitOfWork' so I can update them myself when the user clicks the "Save" button (or "Update" button). Course, if you were assuming I didn't read the docs, I can see how you could come to this conclusion; but I have read the docs and I am attempting to use the control with that knowledge in mind.
As far as 'writing code' - we have very sophisticated dynamic form framework that was written to create all the form controls and do all the reading/writing/validation/lookups between the form and the database. It stores all the values for the forms and fields in a data dictionary that also indicates the validation logic as well as input and output formatting. So I can't just "drop the control on a page" - there is no page for us - all that is ever on a page for us is a "placeholder". There are times I wish we could just create a form "manually" but then when I'm on the phone with a client and they ask "can you add a new field between field A and field B" and I say "hold on..." and then 1min later I say "refresh your browser" and the field just shows up, with validation, with lookups, with storage to the database...then I realize the beauty and power of having all your database structure and logic in one place; not hard-coded on the form.
At this time, after hrs of work, I DO finally have a version semi-working - but there are some very odd behaviors with the DataSource.
I'll post the code in a bit and my hack/fix and my questions.
I still want to know why my "DataSource" seems to always need to be refreshed. They only way I can get it to work is to store my OWN copy of the datasource and keep track of it myself and stomp relentlessly on the LlblGenProDataSource at all times since the one in the LGP DS is always wrong (either it has the wrong data in it, or it has 0 records)
I will say that when I set "LivePersistence=True" it works flawlessly...but for "LivePersistence=False" I find the functionality counter-intuitive and in some cases even broken. Of course, it could be I just don't understand the wonderful wizardry that is going on to make it work and I'm walking into the wall beside the door instread of thru the door (I have a flat spot on my head from doing that before)...which is why I asked for help
Thanks for your assistance.
Andrew.
Before I'll address the rest of your points, the reason why you get a fetch call every time is because of the selectparameters: these make it fetch new data every time. This is because the filter can change. Normally it won't do this, but with select parameters, it has to, otherwise you wouldn't get new data being fetched when the selectparameter's value changed. It doesn't do this by default. Some weeks ago this was fixed, as it did fetch everytime even if you just clicked a button.
Keep in mind though that the datasourcecontrols are very badly documented by MS, work very odd and are written with a hardcoded page in mind (not by me, I just followed what was necessary to get these things working. Which was a long struggle). This means that with your dynamic framework it's probably not working, but all we can do is stick with the rare info MS provided and what ASP.NET requires. In these settings, it works well.
It's NOT broken, NO-ONE knows how these datasourcecontrols should work as there's NO DOCUMENTATION provided by Microsoft how you should implement one which does more than the tictactoe crap they document themselves. So we did the best we could and our datasourcecontrol is very feature-rich and works OK in normal settings. What more can we do? We test it with the vanilla controls MS ships, using normal webforms. That's all we can do.
Livepersistence=false is a setting we added to allow people to do the persistence logic themselves. If you get one call per row, that's ASP.NET and the grid, NOT us. You get 1 postback per row so only ajax code can solve this. Yes that's counter intuitive, it might suck but that's how it is and I can't change it because datasourcecontrols are passive objects: they act upon a call from the bound grid/control. A control calls them to do something, they do it, cycle ends. If a control calls ExecuteUpdate, the datasourcecontrol has to do that, it can't cache the action, because it doesn't know when everything ends, so it has to respond to actions it recieves.
EVERY postback the datasourcecontrol gets a call to ExecuteSelect. Every postback. So also when a selectparameter changes. Or whatever reason. If a selectparameter changed, the filter is changed and the data is refetched. There was some bug in our code some time ago with postbacks on buttons and selectparameters. This has been fixed some time ago, so I'm not sure which runtime build you're using, but if you're not using the latest build I suggest to check that out.
But as you might see now: this whole datasource crap is one big hack. I keep a lot of state info behind the scenes just to make it work intuitively and for example to only fetch new data when it really has to. This is because asp.net by itself doesn't do this: it doesn't give a full form awareness, so as a programmer you're still working with request-response-endoflife programming where everything rebirths at request and everything dies at response end. Datasources try behind the scenes as good as they can to keep up the facade that this doesn't happen, that it's one big statefull application.
So, calling it broken is silly. Yes something is broken. It's asp.net, not the datasourcecontrols. But it's what we have and what we have to work with, so we do our best to get a working datasourcecontrol despite the lack of any info worth mentioning. I think it works OK now, though it of course requires you run the latest build of the runtimes.
And be sure to update everything in your webapp with that latest runtime. VS.NET is so crippled and buggy in this area that it won't hesitate to keep an old one around.
If I sound frustrated about these whole datasource mess, yes I am. But I can't change the world so it's what we've to work with and what we can offer you. Though just try the latest builds, they're likely to fix the problem you ran into.
Joined: 28-Mar-2006
Frans:
First, no problem with appearing frustrated; I know what I trial working with the datasources must have been; we have had our own share of issues with our dynamic framework dealing with various MS "issues."
Second, when I said "broken" I didn't mean to imply your implementation was broken, only that it appeared to me that it was not acting as it should. I probably should have done what I tell my clients to do: indicate what I expect and then what it did - sometimes we write code to do A and a client expects it to do B, in that case, it is an issue of "design" not of a "bug." I realize more now that you can only do so much when working within an existing architecture (and the more I learn about the datasource architecture, the more frustrated I get...)
Third, whether you think so or not, your answers were very helpful! I consider all the "datasource" code and framework produced by MS to be a minefield and anyone that can come along and show me where a few mines are is a welcome ally
Fourth, I think your implementation of the "datasource" works great; I think the issue I am having (and as I have read, others have had as well) has nothing to do with your datasource "working" or "not working", it is our lack of understanding (due to the lack of documentation) of MS's "datasource framework" - to that end you are a valuable resource since you have more "documentation" in your head than exists in print. Please don't ever give up helping us through these pitfalls (and thank you for your thick skin)
Thank you very much for your help.
I apologize for any offense; none was intended - I'll try to direct my frustration at MS where it belongs
Andrew.
THanks Andrew
I think this:
I probably should have done what I tell my clients to do: indicate what I expect and then what it did - sometimes we write code to do A and a client expects it to do B, in that case, it is an issue of "design" not of a "bug."
is a very good approach and would work great for us I think. So in this or other threads if you could specify it like you describe in the quote above, it would be very helpful.