This is a migrated thread and some comments may be shown as answers.

Weird behaviour of scope.IsDirty(object, string)

6 Answers 68 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Tomasz M.Lipiński
Top achievements
Rank 1
Tomasz M.Lipiński asked on 25 Jan 2010, 11:53 PM
Hi,
I have the following piece of code:
string queryString = "SELECT * FROM UserExtent WHERE ...";  
IQuery oqlQuery = pScope.GetOqlQuery(queryString);  
IQueryResult result = oqlQuery.Execute(new object[] {...});  
if (result.Count > 0)  
{  
  User user = result[0] as User;  
...  
  user.USRIsLockedOut = pDTO.IsLockedOut;  
  if (pScope.IsDirty(user, "USRIsLockedOut"))  
    .. do something 
"User" is a persistent data class. pScope is a scope with an open transaction. pDTO is a Data Transfer Object that brings new data. Both: user.USRIsLockedOut and pDTO.IsLockedOut are of type "bool" and have the same value (it is the result of a trivial sequence: open the form (for editing), click "Save" without touching anything).
The expected value of pScope.IsDirty if, of course, false: but it isn't, of course (I wouldn't be here if it was...).
But - another and the most intriguing "but": if I check (under the debugger (Visual Studio 2008)) the value of user.USRIsLockedOut (just hover the mouse over it), pScope.IsDirty becomes false.
Is something wrong with this code? I feel lost....

Regards
Tomasz

PS. I'm using 2009.3.1104.2 version of Open Access.

6 Answers, 1 is accepted

Sort by
0
Damyan Bogoev
Telerik team
answered on 28 Jan 2010, 06:12 PM
Hello Tomasz Lipinski,

Unfortunately we were not able to reproduce the problem. Please have a look at the attached solution, it may help you to resolve the issue. And please do let us know if you see any differences between our and your project that might be causing this behavior.

Greetings,
Damyan Bogoev
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Tomasz M.Lipiński
Top achievements
Rank 1
answered on 28 Jan 2010, 08:21 PM
Hi,
Well, the attached solution behaves exactly as I've described. I've created a user with USRIsLockedOut = true.  When ran without interfering, the program says "Do something...". When I check values with the debugger, says "Do not something...".

My OS is Win XP SP3. OpenAccess: 2009.3.1104.2. Visual Studio: 2008 SP1. SQL Server 2005 (it doesn't matter whether it is SQLEXPRESS or SQL - both work in the same way).

Regards
Tomasz
0
Damyan Bogoev
Telerik team
answered on 01 Feb 2010, 05:58 PM
Hello Tomasz M.Lipiński,

The problem is that when you are watching the object’s properties in the debugger, it alters the runtime behavior as displaying the properties requires them to be loaded. When they are loaded, if the new and old values are equal, the IsDirty method returns false because there is no need of modifying the property’s value. In the other cases the object’s properties are not loaded from the database and the IsDirty method always returns true because the value is changed without comparing the new and old values.
You could disable the property evaluation setting by following those steps:

1. From the Tools menu, choose Options;
2. In the Options dialog box, open the Debugging folder and select the General category;
3. Clear the Enable property evaluation and other implicit function calls check box;

Hope that helps.

Kind regards,

Damyan Bogoev
the Telerik team


Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Tomasz M.Lipiński
Top achievements
Rank 1
answered on 02 Feb 2010, 10:20 AM
Hi,

I understand the reason but your proposal goes in a wrong direction. The truth is that the new and old values are equal. The goal is to force OA to see the true old value without the debugger's support.
Should I use the scope.Retrieve method? Or any other way to make the "user" object really loaded?

And by the way: what is the sense of comparing any value with something that is not loaded? Shouldn't you raise some exception in such a case (or, maybe, load the object automatically)?

Regards
Tomasz
0
Accepted
Damyan Bogoev
Telerik team
answered on 03 Feb 2010, 01:31 PM
Hello Tomasz M.Lipiński,

There two solutions to this problem.
The first approach you could use is short transaction boundaries. In case of write operations inside this method you should commit the transaction immediately after the write operations end:

scope.Transaction.Begin();
//write operations
scope.Transaction.Commit();

When the transaction is committed all the modified fields are marked as persistent clean(not dirty).
The second approach is to use the IObjectScope.Refresh(persistentObject) method. It will refresh the state and values of the persistent object from the database.
Hope that helps.

Best wishes,
Damyan Bogoev
the Telerik team

Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Follow the status of features or bugs in PITS and vote for them to affect their priority.
0
Tomasz M.Lipiński
Top achievements
Rank 1
answered on 03 Feb 2010, 07:43 PM
Hi,
OK. I think that I've misunderstood (a little) the meaning of IsDirty. I've thought that IsDirty = true means: "the filed should be written to the database because its value is different from this in the database". But it actually means: "the field is dirty because something has been stored in it - regardless how it is related to the value in the database".

Thanks for the explanation
Regards
Tomasz
Tags
General Discussions
Asked by
Tomasz M.Lipiński
Top achievements
Rank 1
Answers by
Damyan Bogoev
Telerik team
Tomasz M.Lipiński
Top achievements
Rank 1
Share this question
or