3

When I use DataSet, there is possiblity to raise events on RowChanging, RowChanged, ColumnChanging, ColumnChanged, etc...

How to do the same with an entity from Entity Framework ?

wonea
  • 4,783
  • 17
  • 86
  • 139
NIF
  • 462
  • 2
  • 7
  • 23
  • Entity Classes is not a DataSet, what problem you trying to solve? – gandjustas Apr 11 '11 at 14:45
  • 1
    Is this a duplicate of http://stackoverflow.com/questions/3460714/entity-framework-how-to-raise-onchanging-for-any-property ? – NateTheGreat Apr 11 '11 at 14:45
  • I have posted an answer to your question [here](http://stackoverflow.com/a/32626552/1016343), showing how to subscribe to the event and how EF handles events. – Matt Sep 18 '15 at 08:49

2 Answers2

5

Entities already implement the PropertyChanged event since they implement System.ComponentModel.INotifyPropertyChanged. If you want to catch changes to your entieis, you can just subscribe to that.

Also note that entities support the following two partial methods—the second of which should give you the equivalent of "RowChanging"—that you can override if you'd like to respond to changes within your class:

protected override void OnPropertyChanged(string property) {}

protected override void OnPropertyChanging(string property) {}
Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
  • Thank you, I seemed to have already seen it somewhere. But what I don't know is : how to "**subscribe**" ? Where do I make changes to make this work ? In "Entities.edmx / Entities.Designer.cs ? Do I need Another class ? Here on this instance ? => MyEntities db = new MyEntities(); ? ... Thank you for your clarification. – NIF Apr 13 '11 at 09:30
3

You can do the following to raise an event on property changed in Entity Framework: Suppose you have the Pubs database - it has a table employee with the following table structure:

Table employee in pubs database

Now we want to track any changes of the property hire_date. You can do it the following way (this example can be used easily in LinqPad - you just need to define a EF datasource and then you can run the example):

void Main()
{
    var test=new employee();
    test.PropertyChanged += HandleSomethingHappening;
    test.hire_date = DateTime.Now;
}

public void HandleSomethingHappening(object sender, EventArgs e)
{
    var propName=((System.ComponentModel.PropertyChangedEventArgs)e).PropertyName;
    var empObj=(employee)sender;
    if (propName=="hire_date")
    {
        Console.WriteLine(propName+" changed to: " + empObj.hire_date.Date.ToString("d"));
    }
}

If you run it, it will show

Hire date changed: 17.09.2015

on the console, because in the main method we changed the property via:

test.hire_date = DateTime.Now;

N.B.

  • To remove the event registration, you can use:
    test.PropertyChanged -= HandleSomethingHappening;
  • As shown here, Lambdas are also allowed; e.g. you could use:
    test2.PropertyChanged +=
    (c, a) => Console.WriteLine(((System.ComponentModel.PropertyChangedEventArgs)a).PropertyName + " property has changed in employee entity");
    which would handle the same event as the example above. But in this case, de-registration is not possible since you cannot refer to the anonymous function implicitly created
  • You can use the PropertyChanging event as well, which will trigger before the change is happening
  • This is not limited to the Entity Framework, you can use it in every class as this SO article shows.

Advanced hints:

If you want to understand better what is going on behind the scenes, I am providing a simplified code of the employee class (just the property and event needed to run the example above):

public class employee //: EntityObject
{


    #region Primitive Properties

    public global::System.DateTime hire_date
    {
        get
        {
            return _hire_date;
        }
        set
        {
            //Onhire_dateChanging(_hire_date);
            _hire_date=value;
            Onhire_dateChanged();
        }
    }
    private DateTime _hire_date;


    void Onhire_dateChanged()
    {
            var handler = this.PropertyChanged; // copy before access (to aviod race cond.)
            if (handler != null)
            {                   
                var args=new PropertyChangedEventArgs() { PropertyName="hire_date" };
                handler(this, (System.EventArgs)args);
            }
    }

    public event EventHandler PropertyChanged;

    #endregion

}


public class PropertyChangedEventArgs: System.EventArgs
{
    public string PropertyName  { get; set; }
}

You can see how the event is wired up - it gets triggered in the property's set method.

Community
  • 1
  • 1
Matt
  • 25,467
  • 18
  • 120
  • 187