How to raise an event on Property Change?

前端 未结 2 877
栀梦
栀梦 2020-12-10 09:30

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 Enti

2条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-10 09:41

    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:

    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.

提交回复
热议问题