简体   繁体   中英

How to raise an event on Property Change?

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 ?

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) {}

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:

pubs数据库中的表employee

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;

NB

  • To remove the event registration, you can use:
    test.PropertyChanged -= HandleSomethingHappening;
  • As shown here , Lambdas are also allowed; eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM