C# Marking Class Property as Dirty

Mark a Business Object as dirty?

This is really a question about concurrency: How do you have multiple users modifying the same business objects and be confident each of their edits will be saved successfully.

If you are storing your objects in the cache, you can create a partial object to include a "IsDirty" boolean property. As an item is checked, you set the IsDirty property of the relevant object to true.

There are many ways to handle concurrency and one way you can try is to check the IsDirty property when an item is checked. If the property is false, you set the property to true. If the property is already true, you send back an error to the user. Once the object is saved, you reset the IsDirty property back to false.

Things can get more and more complicated as you try to get more sophisticated with the rules you create for saving your objects.

How can I mark a form/field as dirty if it's databound?

try implementing

public partial class Window1 : INotifyPropertyChanged

and then

public event PropertyChangedEventHandler PropertyChanged;

public string UserName
{
get { return _UserName; }
set { if (value != _UserName)
{
_UserName = value;
OnNotifyPropertyChanged("UserName");
}}
}

private void OnNotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}

and databind like

<TextBox Text="{Binding UserName}"/>

Different ways to implement 'dirty'-flag functionality

For my DAO I keep a copy of the original values as retrieved from the database. When I send it to be updated, I simply compare the original values with the current. It costs a little in processing but it is a lot better than having a dirty flag per property.

EDIT to further justify not having a dirty flag: if the property returns to its original value, there is no way to reflect that, the dirty flag continues dirty because the original value was lost.

Mark object (not entity, not framework) as dirty in WPF ViewModel

From the sound of it:

  1. Add a IsDirty property onto your SomeDomainType
  2. In the setter of IsDirty raise the NotifyPropertyChanged event for IsDirty
  3. In all of the properties on your SomeDomainType that you change to make the object considered Dirty, in their setters, set IsDirty to true

This is presuming your SomeDomainType implements the INotifyPropertyChanged interface. If not, create a wrapper class around the SomeDomainType that does, and make the above changes to that wrapper.

How to make NHibernate considered property to always be dirty when using dynamic update or insert?

NHibernate provides many places for extension. Among them is the Session IInterceptor. There is documentation with many details:

http://nhibernate.info/doc/nh/en/index.html#objectstate-interceptors

In this case, we can create our custom one, which will be observing our entity (for example Client) and a property which must be updated every time (for example Code). So our implementation could look like this:

public class MyInterceptor : EmptyInterceptor
{
public override int[] FindDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, NHibernate.Type.IType[] types)
{
var result = new List<int>();

// we do not care about other entities here
if(!(entity is Client))
{
return null;
}

var length = propertyNames.Length;

// iterate all properties
for(var i = 0; i < length; i++)
{
var areEqual = currentState[i].Equals(previousState[i]);
var isResettingProperty = propertyNames[i] == "Code";

if (!areEqual || isResettingProperty)
{
result.Add(i); // the index of "Code" property will be added always
}
}

return result.ToArray();
}
}

NOTE: This is just an example! Apply your own logic for checking the dirty properties.

And we have to wrap Session this way:

var interceptor = new MyInterceptor()
_configuration.SetInterceptor(interceptor);

And this is it. While Client is marked as dynamic-update, the property Code will always be set as dirty

<class name="Client" dynamic-update="true" ...

Flagging an object as changed

There is no built-in solution. You could implement a function for your setters, but it still requires that all setters are correctly calling this function.

Here's an example:

private bool _changed;
private void SetValue<T>(ref T field, T value)
{
if (!Equals(field, value))
{
field = value;
_changed = true;
}
}

private string _foo;
public string Foo
{
get => _foo;
set => SetValue(ref _foo, value);
}


Related Topics



Leave a reply



Submit