Refresh object from DB after update

Refresh object from DB after update

Old forum URL: forums.lhotka.net/forums/t/2039.aspx


FreeAsInBeer posted on Wednesday, December 27, 2006

I'm new to CSLA, so if I've missed something obvious please forgive me.

I noticed this bit of code from the PT demo;

    private void DoInsertUpdate(SqlCommand cm)
    {
      cm.CommandType = CommandType.StoredProcedure;
      cm.Parameters.AddWithValue("@id", _id);
      cm.Parameters.AddWithValue("@name", _name);
      cm.Parameters.AddWithValue("@started", _started.DBValue);
      cm.Parameters.AddWithValue("@ended", _ended.DBValue);
      cm.Parameters.AddWithValue("@description", _description);
      SqlParameter param = new SqlParameter("@newLastChanged", SqlDbType.Timestamp);
      param.Direction = ParameterDirection.Output;
      cm.Parameters.Add(param);

      cm.ExecuteNonQuery();

      _timestamp = (byte[])cm.Parameters["@newLastChanged"].Value;
    }
After a successful update, shouldn't we re-get the object from the DB? This is in case the DB itself has changed some of the values upon update. The only value that this is happening for is _timestamp.

I'm sure I read in the Rocky's book that that is what he does, but i don't see the mechanism for it here.

Many thanks

Brian Criswell replied on Thursday, December 28, 2006

The assumption is that you just sent all of those values to the database, so there is no need to update them.  If something else had changed some of those values since you retrieved the object from the database, then the update should fail because the other change should modify the timestamp, which will no longer match the object's timestamp.  The only thing that needs to be updated is the timestamp, because the update will have changed the timestamp on the server and the object will need the new timestamp in case of a subsequent update.

FreeAsInBeer replied on Thursday, December 28, 2006

Brian Criswell:
The assumption is that you just sent all of those values to the database, so there is no need to update them.


That seems a dangerous assumption to me, it means you can't have a single piece of database logic that changes a value. Unless ofc that logic is also in the Business layer, ie in the class itself.

I'll try to think of a non-contrived example and get back asap.

Edit: thought of one...calculated fields. We still use them dont we?



Brian Criswell replied on Thursday, December 28, 2006

Obviously if you have a database trigger doing a calculation (or insert some other example here) then you will also need to retrieve that value.  But the bulk of the database items, especially in the example cited, are purely data storage with no behaviour.  One of the concepts pushed in the CSLA books is that as much of the behaviour and changing of data is performed by the business objects and the database does little more than data storage whenever possible.  All (or as much as possible) of the applications behaviour and changes goes through the business objects, so the assumption is generally a safe one, and it allows for exceptions to be made.

So to recap:
One thing to remember is that the examples show just one way to do things.  I have seen CSLA business objects use other data sources, retrieve more values after an update and many other things.  The templates/examples are there to give you an example of how to structure your own objects, but you are free to make your own objects behave how the need to behave, including retrieving addtional fields if necessary.

FreeAsInBeer replied on Thursday, December 28, 2006

Brian Criswell:
One of the concepts pushed in the CSLA books is that as much of the behaviour and changing of data is performed by the business objects and the database does little more than data storage whenever possible.


I get you, but 'as much as possible' != 100% .

I've always found it disappointing when the wonderful tool we have, relational databases, are relegated to 'little more' than simple data storage tools. They can, and should, be a lot more than that.

Re-getting the object after an update is not a hard thing to do. I was mainly trying to get a feel for why Rocky has done things the way he has (in that demo).

Brian Criswell replied on Thursday, December 28, 2006

I know what you mean, but on the flip side, I have been burned by projects that used the features of a RDBMS too much/improperly.  I have found that the .NET framework and the business objects built on CSLA have allowed me to really place all the behaviour of a single object in a use case into a single business object, and that has been a really powerful revelation.  I have worked on projects where everything was done in the database and the UI did a little bit of extra stuff along with loading and saving the data.  Understanding where concepts began and ended was a nightmare.

Relearning object oriented design (David West's Object Thinking is a good if idealistic book) has really helped me understand how to conceptually organise and build my applications so that they are more easily maintainable and understandable.  Putting behaviour (such as a calculation on update) into the database blurs the lines of where the object begins and ends and makes maintainability a little more difficult, but at times it is the best way to do things.

The thing I think is most useful about RDBMSs for where I am on my journey at the moment is that they allow you to store data once and have different objects be built from different views of the data.  This really helps with breaking away from the "one table per object" or "use every database field in an object" modes of thinking.

As for what Rocky was thinking, aside from just asking him, you can look at the book where he describes the setup of the objects and database.  Getting the object is not difficult, it just requires lots of output parameters on a stored procedure an additional select if you are using an ORM package.  If you actually just have the UI get a new copy of the object, you need to update all the references in the application to that object.  So for me (and what the book demonstrates) the easiest thing is to just get the minimum information needed.

The nice thing is that you can do it whichever way you want.

BTW welcome to the community.

FreeAsInBeer replied on Thursday, December 28, 2006

Brian Criswell:
If you actually just have the UI get a new copy of the object, you need to update all the references in the application to that object.  So for me (and what the book demonstrates) the easiest thing is to just get the minimum information needed.

The nice thing is that you can do it whichever way you want.

BTW welcome to the community.


Ahh. that was my plan. After the successful update just do a get. As you said, I've just got to make sure all references update.

Thank you for the welcome, and replies :)

FaiB

ajj3085 replied on Thursday, December 28, 2006

FreeAsInBeer:
That seems a dangerous assumption to me, it means you can't have a single piece of database logic that changes a value. Unless ofc that logic is also in the Business layer, ie in the class itself.


I would think that any such logic would be in the BO.  Part of what you're trying to do is keep the logic out of the database.  Now, it may be the case that your db does create some value, and in that case, you'd probably return that data as an output parameter and have the BO read the result, just like it does the version.  But why re-read data which you know isn't different?

FreeAsInBeer:
thought of one...calculated fields. We still use them dont we?


Wouldn't the BO have a field which is the result of the calculation?  Why would you have the database calculate the value?  I'm hard pressed to think of a calculation which doesn't involve the set that would be faster on the db.  And even if it is, do a very few milliseconds matter?

Copyright (c) Marimer LLC