The EditableRootList approach:
- Allows us to save all rows at the end of the users input.
- Consistent with our current interface.
- if a few hundred rows are displayed, this approach creates a large n-level undo snapshot and send a lot of data back to the server when saving, eg a few meg to save a few rows is quite an overhead.
- Conceptually the root collection hosts no business functionality other than to list the search results, ie there are usually no rules applied across the collection itself, rather the rules are in each of the child objects.
- N-Level undo is probably not required for these types of grids as refetching would suffice
What are people doing to support grid editing of a few hundred rows?
- Makes us save each row as editing is finished on the row.
- Saving as you go might slow down editing as there is a pause after the each row to get across the network to the database.
- Conceptually perhaps better because there are usually no business rules to enforce between the objects in the list, use case for editing a list of User objects is simply to be able to update each user in isolation from the others.
- N Level undo would apply to each root object and so would match row editing and allow changes to a single row to be cancelled - which would be appropraite.
Just a few random thoughts….
ERLB saves as you go in Silverlight, just as it does in .NET, essentially
when you switch rows. There should not be a pause because save (like any
other operation in CSLA SL) is asynchronous. Cancelling of changes
however is another story. You have to train your users to hit Cancel to
discard an edit on existing cell, and Cancel+Cancel to discard changes to all
cells in current row. This is not as intuitive of a UI as you might like
for your users. I personally think that BLB with a cancel / save buttons
makes a better UI. No, it is not possible to only send dirty rows from BLB
out-of-the-box. There were a few threads on the forum that described that
people wrote a code to do just that, but CSLA does not support it in itself due
to data consistency concerns, etc…. You can probably do it on your
own if there is a very compelling reason to do so. I am not sure how big
of a hit on memory you take. I’d be curious to find out if you can take
those measurements.
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Magenic ®
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: Ash002
[mailto:cslanet@lhotka.net]
Sent: Tuesday, September 16, 2008 11:45 PM
To: Sergey Barskiy
Subject: [CSLA .NET] Grid Editing Techniques with CSLA for Silverlight
Hi All
We are trying to establish our grid editing basics for a new application. This
is a re-engineering of a current app. Our basic edit page will populate a grid,
allow editing, and then allow the user to click save when their editing is
done, saving muliple rows back to the server.
The two alternatives CSLA seems to offer are: a BusinessListBase class
containing child BusinessBase objects, or an EditableRootListBase containing
root BusinessBase objects.
The BusinessListBase approach:
The
EditableRootList approach:
What are people
doing to support grid editing of a few hundred rows?
Is it possible to save only the
dirty objects from an EditableRootList?
Is it possible to save only the dirty objects from a BusinessListBase?
eg Create a new instance of the list and copy in only the dirty objects?
Is this way off track?!?
Thanx in advance
Ashley
Ash002:if a few hundred rows are displayed, this approach creates a large n-level undo snapshot and send a lot of data back to the server when saving, eg a few meg to save a few rows is quite an overhead.
Ash002:Conceptually the root collection hosts no business functionality other than to list the search results, ie there are usually no rules applied across the collection itself, rather the rules are in each of the child objects.
Ash002:N-Level undo is probably not required for these types of grids as refetching would suffice
Ash002:The EditableRootList approach: Makes us save each row as editing is finished on the row.
Ash002:Saving as you go might slow down editing as there is a pause after the each row to get across the network to the database.
Ash002:Conceptually perhaps better because there are usually no business rules to enforce between the objects in the list, use case for editing a list of User objects is simply to be able to update each user in isolation from the others.
Ash002:N Level undo would apply to each root object and so would match row editing and allow changes to a single row to be cancelled - which would be appropraite.
Ash002:What are people doing to support grid editing of a few hundred rows?
Ash002:Is it possible to save only the dirty objects from an EditableRootList?
Ash002:Is it possible to save only the dirty objects from a BusinessListBase?
Ash002:eg Create a new instance of the list and copy in only the dirty objects?
Hi Guys,
Thanks for the extensive input.
To summarise/clarify a little -
Our need is to create a UI using grids.
The saving speed of 100 rows is probably ok, its the saving of 200, 300 or 500
rows which concerns me. The user will then make changes to a few rows and press
a save button. The save button is required for consistency with the old app and
for consistency within the new app.
EditableListRootBase does not, in its
current form, fit with the save button, as rows are saved automatically on row
exit - and it has no option to postpone saving.
Silverlight's async approach is cool and
certainly would help with any delay occuring on row exit, but we need to use a
save button for the sake of consistency as stated.
I understand the snapshot does not travel
over the wire, so its only a single copy of the data that travels on the wire.
Yes this could be an anti-pattern of
premature optimisation and the testing of the theory needs to be done. This
application however will be sold commercially to many customers, and we can't
afford to be clobbering their network with our app, and we want to be able to
run over the internet. Thats the advantage of silverlight. If the option to
send/recieve less data exists I would use that where appropriate.
You point is well taken about the risk of
not sending the whole object over, and the nessecity of the clean objects on
the server. There are certainly many cases where that is true. Eg form style
pages which involve more complex object relationships, or a grid such as a
timesheet.
However there are many use cases where
you don't need the clean objects on the server - ie anywhere you could use an
EditableListRootBase. In these cases the business objects themselves make sense
as root objects, ie self contained behaviours and rules.
But I have now learnt that saving only
the dirty objects in a single save is not an out of the box feature.
Many Thanks
Ashley
From: ajj3085
[mailto:cslanet@lhotka.net]
Sent: Wednesday, 17 September 2008
10:47 PM
To: Ashley Dickson
Subject: Re: [CSLA .NET] Grid
Editing Techniques with CSLA for Silverlight
Ash002:
if a few hundred rows are displayed, this approach creates a large n-level undo snapshot and send a lot of data back to the server when saving, eg a few meg to save a few rows is quite an overhead.
Um, not quite. N-level undo data doesn't transport; you MUST get your
editlevel back to 0 by canceling or applying edits prior to calling save.
However, if a user only changed 5 out of 100 rows, the other 95 DO get sent
back. But the undo snapshots are NOT part of the stream. That's ok
though; the unchanged objects are still part of the parent's state, and need to
be included technically.
Ash002:
Conceptually the root collection hosts no business functionality other
than to list the search results, ie there are usually no rules applied across
the collection itself, rather the rules are in each of the child objects.
In practice this is true, because there's no way for the collection itself to
report errors back to the UI via the IDataErrorInfo interface, nor does it have
broken rules. But your rules would likely be on the child object
anyway. If you need rules across the collection, you could create a
parent BusinessBase which has the collection BLB as a child, and run rules
there. This also gives you a chance to report the rules.
Ash002:
N-Level undo is probably not required for these types of grids as
refetching would suffice
Then you don't need to use n-level undo. For a user experience that users
will expect though, DataBinding will still call BeginEdit / Cancel or
ApplyEdit. You shouldn't disable that, because users won't get the
expected grid behavior (namely pressing ESC to cancel changes to a row).
The binding undo behavior is handled by the n-level undo logic.
Ash002:
The EditableRootList approach: Makes us save each row as editing
is finished on the row.
Yes; ApplyEdit will cause the row to Save.
Ash002:
Saving as you go might slow down editing as there is a pause after the
each row to get across the network to the database.
Yup. It may not even be that noticable though.. but only testing in your
environment will tell.
Ash002:
Conceptually perhaps better because there are usually no business rules
to enforce between the objects in the list, use case for editing a list of User
objects is simply to be able to update each user in isolation from the others.
That depends on the use case. But if your use case says all the updates
are done as a single batch, this isn't the way to go. Remember, a root
object is the one controlling the database transaction.
Ash002:
N Level undo would apply to each root object and so would match row
editing and allow changes to a single row to be cancelled - which would be
appropraite.
The same experience would apply to the BLB root class as well. The only
difference is that ApplyEdit here will commit to the database; ApplyEdit on the
BLB child will just "save" the user's changes to the row (which would
only be undo-able by reloading the list, unless you do more to use n-level
undo).
Ash002:
What are people doing to support grid editing of a few hundred rows?
It depends on the specific use case. ">
Ash002:
Is it possible to save only the dirty objects from an EditableRootList?
Well, that's what happens by default. Since each object in the list is a
root, that object goes back and forth by itself; it has no idea it's even part
of a collection. Which means you can't have rules that work
"across" the collection.
Ash002:
Is it possible to save only the dirty objects from a BusinessListBase?
Yes, but the entire object graph will travel to the server in a remoting
setup. But clean objects wouldn't communicate with the database, if you
code it that way.
Ash002:
eg Create a new instance of the list and copy in only the dirty
objects?
You could do that, but you'd be working with the "premature
optimization" anti-pattern. Have you even tried the BLB with 100
objects to see how it performs? There are also other ways to reduce
network traffic; you could use the CompressedDataPortal, for example. But
before you do anything, I'd see how it works as-is.
Also, there's a danger when you only try to save part of the objects state; the
clean objects might be necessary on the server, for example if rules need to be
re-run. If they're not there, you may get broken rules when you
shouldn't, or worse, not get broken rules when you should. You also need
to worry about how to update the BLB and it's children in place, rather than
just replacign the reference and rebinding the UI.
I recommend trying to send only dirty BOs across the wire; it's not going ot
make saving noticably faster, and there are many hidden dangers.
The choice to use Silverlight has been
made and we have been working with Silverlight and Csla for Silverlight a few
months now.
You are right to point out that we need
to do the experiment however. The amount of data which produces an acceptable
load time, would probably result in an acceptable save time. We could just
provide an option to set the results size, and users could set according to their
situation.
As to making an arrangement to save only
the dirty data, I would be more inclined to use EditableRootListBase than BLB.
ERLB seems to be the result of the thinking involved in the Csla paradigm. Ie root
objects travel on their own, child objects travel with the root. So ERLB not
sending the updated objects until a save button click, and then sending all the
saved objects, seems to be in keeping with csla principles. A BLB with missing child
objects, seem to be outside of those principles.
In the case where there are business
rules across the grids rows, then the BLB arrangement would be the right choice.
But in those cases I wouldn’t be inclined to optimise and send back only
dirty data. As that creeps into risky territory. I think ERLB would cover most
circumstance and keep it simple as you say.
Actually this idea seems a natural
extension to ERLB. The principle being that the objects’ only business
relationships with each other is that they happen to be on the same grid. In
that sense ERLB is a view technology.
That said I have played with overriding
ERLB. Postponing saves is easy. I then create “copies” ERLB,
legitimate as ERLB is just view/collection of BOs. Then clone each dirty or
deleted BO, add to “copies” and pass copies to DataPortal Update().
On the server side call SaveItem() for each item in copies. All seems too damn
simple. There is the issue of getting the objects back into the original ERLB, with
new IDs etc, and checking to make sure Clone() is a deep clone (I am kinda
assumming that as Clone is essential to Csla and its snap shots etc).
Will see how iit all goes.
Ash002:In the case where there are business rules across the grids rows, then the BLB arrangement would be the right choice. But in those cases I wouldn’t be inclined to optimise and send back only dirty data. As that creeps into risky territory. I think ERLB would cover most circumstance and keep it simple as you say.
If you really want to only transfer datagrams, not object graphs, you should consider using the local data portal and calling your own custom WCF services that return/consume datagrams. That may be a simpler overall solution.
Yes, you give up the mobile object features of the data portal, but it sounds like you really don't want them anyway (mobile objects and datagrams are different models).
That is true, ERLB does coordinate autonomous root objects. And
if you user’s are good with that experience (no cancel button, etc) then
it is a great option!
BLB is a good option too – for the same scenarios, but
with different user expectations around when things commit and can be canceled.
But if you want BLB semantics, and only want to transfer changed
data (which I thought was discussed earlier in the thread), then you enter the
realm of datagrams. CSLA doesn’t do that, because it provides an
inconsistent object model and context on the client and server. Not that that’s
always bad, but it is outside the goals for the data portal, which is all about
providing a consistent object model and context on both sides of the wire.
Which is why you have the option of using the local data portal
(globally, or for specific objects), in case you want datagram semantics in
certain (or all) scenarios.
I’m not trying to push you one way or another – just
trying to compartmentalize the concepts and their application.
The real world is full of gray areas. But gray areas waste time
and money, so personally I always force gray areas into one box or another.
Much like Stephen Colbert’s attitude (to paraphrase): mobile objects or
datagrams, pick a side! :)
Rocky
Hi Rocky
I am glad you have been talking about
releasing Csla material which covers a wider range because that would help us
know how Clsa is being used. I know it must seem logical when you already know
it.
We don’t just want to send changed
data, that’s just one possible solution. “Use case” is
Silverlight client with an internet connection to the DB. An ADSL 1 connection
for example has pretty slow upload speed, but ok download speed. Necessity: an
example grid had over 11meg of serialised mobile objects when loading 1400
rows. With only an moderate amount of columns. So 200 rows = 1.5 meg. That’s
still quite a download over the net. For a save its 1.5 meg up and 1.5 meg
down.
We want the object model too, and the
mobile objects.
Paul has done some quick work in
compressing the data portal transfers in the Silverlight data portal with good
results. We could apply compression once a threshhold size is reached. So we
will see how this goes and start off using vanilla BLBs.
Thanks for your input.
Copyright (c) Marimer LLC