1

I’m building WPF app, and I got to the point where I want to be able to check whether an entity IsDirty, so I found this solution online:

private bool isDirty;

    public virtual bool IsDirty
    {
        get { return isDirty; }
        set { isDirty = value; }
    }

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        OnPropertyChanged(true, propertyName);
    }

    protected void OnPropertyChanged(bool makeDirty, [CallerMemberName] string propertyName = "")
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

        if (makeDirty)
        {
            isDirty = makeDirty;
        }
    }

Then I can use it like this

    [Required(ErrorMessage = ErrorMessages.DescriptionRequired)]
    [StringLength(60, ErrorMessage = ErrorMessages.DescriptionLength60)]
    public string Description
    {
        get { return description; }
        set
        {
            if (description != value)
            {
                description = value;
                OnPropertyChanged();
            }
        }
    }

And it seems to work, anytime a property is changed the entity will get dirty because OnPropertyChanged is called. The problem I have is when I load an entity (or collection of entities) from a database, then onpropertychanged is called:

SomeEntitiesCollection = new Service().SomeEntities();

Then each entity which comes is marked as dirty, and I cannot find anyway around it, apart from going through a loop and setting IsDirty back to false. Is there anyother way of achieving it?

Regards

adminSoftDK
  • 2,012
  • 1
  • 21
  • 41
  • Why do you need `IsDirty` property? For change tracking? – Vlad Dec 02 '14 at 09:35
  • Because my Entities are in disconnected state, and I want to be able to prompt the user when edit is cancelled, and any of the property was modified. – adminSoftDK Dec 02 '14 at 09:38
  • Why you can't simply *reset* `IsDirty` after object is loaded from database? Construct it as usual, set properties, `IsDirty == true`, reset `IsDirty = false` (do not call `OnPropertyChanged` obviously), it will stay `false` until property will be changed. – Sinatr Dec 02 '14 at 09:52
  • Since you're using Entity Framework, and Entity Framework already does change tracking, why not simply use that instead of creating your own? –  Dec 02 '14 at 09:52
  • @Sinatr Hi, this is what I do at the moment, if that is a single entity I set the IsDirty back to false, if that is a collection I go through a loop and set them back. I just though there maybe a way around it, to turn that check before I load them and turn it back on after I load them. But I don't know how to achieve it, and whether there is some kind of pattern for it. I think it is a common scenario for everyone. – adminSoftDK Dec 02 '14 at 09:59
  • @hvd yes it does, but im using short running contexts, so as soon as entity/ies are loaded i get rid of the context, so there is no tracking. – adminSoftDK Dec 02 '14 at 10:01
  • @adminSoftDK, I am not using EF, so I am not sure how objects are instantiated. Is there a query what creates objects (construct them with default constructor and setting properties) which you can modify to set `IsDirty = false` at same time? – Sinatr Dec 02 '14 at 10:01
  • @Sinatr hi thanks for the suggestion, but setting it in the constructor will not help, as after it, all properties are set to the values which came from a db, so onpropertychanged is called, and therefore it sets it up to isdirty = true. – adminSoftDK Dec 02 '14 at 10:05
  • Normally I'd then suggest the `ObjectMaterialized` event, which is supposed to get raised after the properties of the object have been set, but since you're working with non-tracking entities, I'm not sure if even gets raised at all. –  Dec 02 '14 at 10:17

1 Answers1

1

no, there isn't an easy way

you should override your method that retrieve entities from db in a way that it sets automatically Isdirty=false on entity creation. I used nhibernate interceptor and events to do something similar but it is not your case.

another way is to keep a copy of all the original values and compute the dirtiness when anyone asks for it. So instead of using a isdirty property you should create a method and save an initial state for all properties

giammin
  • 18,620
  • 8
  • 71
  • 89
  • Any code exmple would be usefull, because I don't know how to achieve it. All it does behing the scene is this using (var context = new ContextService()) { return new ObservableCollection( context.Category); } – adminSoftDK Dec 02 '14 at 09:42
  • @adminSoftDK I don't know how entity framework works internally. as I said I use nhibernate. I just give you an hint on where to watch – giammin Dec 02 '14 at 09:44
  • @adminSoftDK another way is to keep a copy of the original state of the properties and compare it when you dirtycheck – giammin Dec 02 '14 at 09:49
  • Hey, I did the original values and it works great and its simpler as well. Thank you :) – adminSoftDK Dec 02 '14 at 16:12