Search code examples
c#ado.netdatasetpartial-classes

Detecting DataRow changes from within a partial class


Let's say I have an interface representing a domain object:

public interface IFoo
{
    Bar Bar { get; }
}

The Bar type is a family of objects, each of which has a slightly different schema. In the database, this is represented as XML (this is a mobile app, so it is simply nvarchar, not a true XML column).

I have a generated DataSet which contains an FooDataTable and corresponding FooRow objects:

// AcmeDataSet.designer.cs

public partial class FooRow : DataRow
{
    public string BarXml
    {
        // Generated get and set
    }
}

I would like to implement IFoo and cache the deserialized instance of Bar:

// FooRow.cs

public partial class FooRow : IFoo
{
    private Bar _bar;

    Bar IFoo.Bar
    {
        get { return _bar; }
    }
}

How can I, from within the partial class, determine that the value of BarXml has changed?

I realize that FooDataTable contains ColumnChanging and ColumnChanged events, but I don't know how to subscribe to them. There is no analog to Linq to Sql's OnCreated partial method and I don't know of another way to hook into the generated constructor.


Solution

  • If I understand you correctly, then your FooRow object (the instance) is an instance of some type that derives from Type DataRow... If so, then since DataRow has a property that references the DataTable, just cast your IFoo variable to a DataRow,

    Inside of FooRow

      public partial class FooRow
      {    
           private void myColumnChanging Handler(object sender, EventArgs e)
           {
                // Implementation
           }
           private void myColumnChanged Handler(object sender, EventArgs e)
           {
                // Implementation
           }
           public void RegisterEvents()
           {
              ((DataRow)this).Table.ColumnChanging += myColumnChanging; 
              ((DataRow)this).Table.ColumnChanged += myColumnChanged; 
           }
       }
    

    Then, in FooDataTable class, add a new factory method, MyNewFooRow()

    public class FooDataTable 
    {
        //  -- Other implementation
        public FooRow MyNewFooRow()
        {
            FooRow fr = this.NewFooRow(); // call the original factory
            fr.RegisterEvents();
            return fr;
        }
     }
    

    and use this new factory wherever you were using the old one...