Good day all,
I need the ability to determine not only if an object is dirty but, if it is, what property is dirty. I am not aware of any way to accomplish this based upon the stock 2.0 framework.
So, my question is a) am I right in stating that the framework does not include this and b) has anyone else done this and if so how?
Right now I am toying with the idea of adding a list, that will hold the dirty properties, to the base class. Then, in the "PropertyHasChanged" method updating that list. I would then expose this list as a property to consumers of the object. However, that may be a bit clunky and doesn't seem like the most elegant way of doing this.
Any ideas would be appreciated.
Thanks!
Dan
Dan,
That sounds like a good plan for what you want to accomplish. A lot of us are using PropertyHasChanged to do a lot of things. Petar's Observer came into existence to handle that very event when he first got started with it. You may want to consider using that and then, instead of updating the "list" in PropertyHasChanged, you can do it by responding to Notification from the Observer anywhere in your program.
Jav
You are correct, the framework doesn't track the list of changed properties.
But your approach is what I'd do were I to add the concept :)
You can do this without altering CSLA btw. You can just create your own intermediate base class to extend BusinessBase<T> - something like
[Serializable]
public abstract class MyBase<T> : BusinessBase<T>
You should be able to override either PropertyHasChanged or MarkDirty and then keep a list of properties that have been changed - which you can then expose through some method or property.
Then your businiess objects will inherit from your new base class rather than BusinessBase<T> and they should get your new feature.
Rocky and Jav,
Thanks for taking the time to respond to my question. I really appreciate the advice both of you provided.
Thanks again!
Hi
I am running into the exact same problem. Have you tried implementing your solution yet? I was also wondering if any of these items would in fact be invalid, because of businerules etc..
In that case when would you process or determine that these are no longer valid changed properties? Very new to CSLA so any help is greatly appreciated.
Thanks
Don
Hello:
One more question, how would you capture the value of the changed property within the PropertyHasChanged(string propetyName) method???
Thank you so much for your help. Really need a hand with this.
thanks again
Don
Hi Andy,
Thanks for the reply. In our case I would have to know both values, we are using a two stage commit process and some updates will be invalidated. In addition, we will have to store history of these transactions for legal purposes.
I created an abstract class that inherits from business base as suggested. The problem is that I only have the name of the property thats changed. I added an additional method - PropertyHasChanged that accepts three parms, propertyName, originalValue, and currentValue. But am I losing out on the functionality of BusinessBase if I go this route. For instance would I have to have a similar method in the BusinessBase class??? Any help is appreciated, just looking for a good solution to this problem.
Thanks
Don
Can you provide a sample of using the property backer field??
Thanks
Don
dstarkey:Thanks for the reply. In our case I would have to know both values, we are using a two stage commit process and some updates will be invalidated. In addition, we will have to store history of these transactions for legal purposes.
I'd really recommend having the stored procedures handle change tracking like I described above. Your BO need not know anything about the auditing and your don't need to keep adding extra code to save the audit information. Also, even if someone circumvents your BO's and executes your procs directly, you still have history information, because the auditing is done in the proc.dstarkey:I created an abstract class that inherits from business base as suggested. The problem is that I only have the name of the property thats changed. I added an additional method - PropertyHasChanged that accepts three parms, propertyName, originalValue, and currentValue. But am I losing out on the functionality of BusinessBase if I go this route. For instance would I have to have a similar method in the BusinessBase class??? Any help is appreciated, just looking for a good solution to this problem.
It's not a simple matter of having the database sproc generate the audit trail. Let me explain my use case a little better. The database sproc generating the audit trail will not work because the data is actually located on two disparate database systems. Here is the scenario:
Employee maint program where employee object is built primarily from a pervasive database that uses a btrieve system and generic stored procedures (stone age, cannot process multiple result sets, and a host of other issues etc.....). So employee object is built, and edited.
Now on the save some fields can be written directly to the database, while others would have to be either approved or denied by an external company coordinator. So this turns into a multiple phase commit. These records [completed and pending] are inserted into a sql server database where they will either be ok'd and sent to the pervasive database as an update record, or be denied where the customer will be notified that his transaction was denied because of "reason deemed necessary by application coordinator". To complicate things further no set business rule exists for accepting or rejecting these transactions. As a matter of fact similar transactions could be handled differently dependind on the circumstance.
I have to devise a system that will have good performance throughout this entire procedure. I designed an employeeChange class that has the property name, old and current values as well as the time stamp and who originally submitted the change. The final process is where the Sql table containing the transaction record is updated with a new time stamp field along with the id of the coordinator who ok'd or denied the update. So if I haven't totally lost you I could use some help. Thanks to everyone paricipating on this thread, it has already helped a great deal.
The employee object is very complex, having collections of paychecks, roles, benefits, deductions, security and company collections of objects. Because of all these object, I implemented Lazy Loading on some of the high processing objects, such as generating the paycheck collection of objects, thoughts on this are welcome as well. HELP PLEASE! Any and all suggestions are welcome
Thanks
Don
First, Rocky that post was very interesting. I've done some reading of a work "Developing Time-Oriented Database Applications in SQL" by Richard Snodgrass which is basically a pragmatic system for designing databases to support mainly the requirement for resource vs. reference data. I have asked the question myself "how difficult/cumbersome/sucky/etc. would it be to store versioned rows in every table in the entire database given I would never again need to wonder who had changed what." Intriguing stuff.
Secondly, I wholeheartedly endorse the concept of an inherited class from the CSLA base BO classes and having your final BOs inheret from them. Take it from someone who hacked the crap out of a previous CSLA version and has vowed to never do it again. :)
Finally, Don I'm a bit concerned about the requirement to store the "old" value of all the BO properties, since as Rocky has stated that ultimately is only 100% meaningful at the database level because of concurrency issues. Three LastName change requests could be pending for the same employee, so of what value is the second one's "original/old" value state? How would it ever be used? I might be convinced it could be of value to have the BO display the current DB value as of the time it was loaded as well as the proposed changed value.
In other words "Sally Jones has requested that the LastName of employee 34526 be changed to 'Smith' and the current DB value is 'Smyth'" seems infinitely more useful than "Sally Jones has requested that the LastName of employee 34526 be changed to 'Smith' and the DB value when the change was requested three weeks ago was 'Smyth'", given that the value could have been changed numerous times in the DB since then. The "current DB value" option provides for the user concluding "oh, the name in the DB already is changed to Smith". At the very least if the value as of the change request is required I would think you'd also have to show all changes since then.
Just a couple of cents worth for you to consider.
dstarkey:Thanks for the reply. It is in fact going to store the current db value and the proposed value. Last name is an example, but suppose someone is changing pay rate. This escalates this scenario quite a bit. I certainly would like to know who authorized joe smiths $50000 pay increase. And be able to take this transaction log to a legal counsel if the change was unwarranted.
Ah, but there's an important distinction there I think - now you're talking about the actual delta itself which is indeed derived from comparing the DB value at the time the property was changed but is also in fact subtly yet significantly different than storing that DB value.
Again I suggest that knowing all parts of "Jane Doe requested Bob Smith's salary be raised by $50,000 to $75,000" are indeed tremendously significant, but that takes on a rather different significance if Sally Smith's request that it be raised to $45,000 was already approved and committed. I just think pragmatically speaking this mechanism as I understand you to describe will be a concurrency nightmare.
dstarkey:Employee maint program where employee object is built primarily from a pervasive database that uses a btrieve system and generic stored procedures (stone age, cannot process multiple result sets, and a host of other issues etc.....). So employee object is built, and edited.
dstarkey:Now on the save some fields can be written directly to the database, while others would have to be either approved or denied by an external company coordinator. So this turns into a multiple phase commit. These records [completed and pending] are inserted into a sql server database where they will either be ok'd and sent to the pervasive database as an update record, or be denied where the customer will be notified that his transaction was denied because of "reason deemed necessary by application coordinator". To complicate things further no set business rule exists for accepting or rejecting these transactions. As a matter of fact similar transactions could be handled differently dependind on the circumstance.
Uck. And I thought my current issues were challenging. By 'no set business rules' I am thinking that the accept or reject is made on some other employees whim, so you just need to carry out the action? Hmm.
The first part of the challenge is that some fields don't need approval. So I would recommend trying to seperate out the editing of those fields from the more sensitive ones. Also, put the senstive fields into a seperate table all together, so that you're only working with row level rollbacks. You'd probably have a business object which contains the new data which needs to be approved, and has a flag; Undecided, Approved, Denied (and possibly denied comments). None of the other fields can be chagned (from your description thus far). Note tht this object should be distinct from your employee editing object. Anyway, the manager either approves or denies, and then you save that information back to the Sql Server database.
The final part would be a windows service, who's only responsibility is to scan the table containing the transactions which must be approved, and applies any that have not yet been applied. This can be done via yet another object. Likely, your DataPortal_Fetch would load just from Sql Server, and your data portal update would update both Sql Server and the pervasive db. You'll have to use DTC here to keep both database updates atomic. (So use Trasnaction.TransactionScope on this method).
From: dstarkey [mailto:cslanet@lhotka.net]
Sent: Wednesday, June 21, 2006 12:47 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: What Property IsDirtyIt's not a simple matter of having the database sproc generate the audit trail. Let me explain my use case a little better. The database sproc generating the audit trail will not work because the data is actually located on two disparate database systems. Here is the scenario:
Copyright (c) Marimer LLC