Détecter les modifications DataRow à partir d'une classe partielle
-
22-07-2019 - |
Question
Disons que j'ai une interface représentant un objet de domaine:
public interface IFoo
{
Bar Bar { get; }
}
Le type Bar
est une famille d'objets, chacun ayant un schéma légèrement différent. Dans la base de données, cela est représenté en XML (c'est une application mobile, donc nvarchar
, pas une vraie colonne XML).
J'ai un DataSet
généré qui contient un FooDataTable
et les objets FooRow
correspondants:
// AcmeDataSet.designer.cs
public partial class FooRow : DataRow
{
public string BarXml
{
// Generated get and set
}
}
Je voudrais implémenter IFoo
et mettre en cache l'instance désérialisée de Bar
:
// FooRow.cs
public partial class FooRow : IFoo
{
private Bar _bar;
Bar IFoo.Bar
{
get { return _bar; }
}
}
Comment puis-je déterminer, au sein de la classe partielle, que la valeur de BarXml
a été modifiée?
Je réalise que FooDataTable
contient les événements ColumnChanging
et ColumnChanged
, mais je ne sais pas comment s'y abonner. Il n'y a pas d'analogue à la méthode partielle OnCreated
de Linq avec Sql et je ne connais pas d'autre moyen de se connecter au constructeur généré.
La solution
Si je vous ai bien compris, votre objet FooRow (l'instance) est une instance d'un type quelconque qui dérive de Type DataRow ... Si tel est le cas, DataRow possède une propriété qui référence le DataTable. Il vous suffit alors de convertir votre variable IFoo. vers un DataRow,
À l'intérieur de 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;
}
}
Ensuite, dans la classe FooDataTable, ajoutez une nouvelle méthode de fabrique, MyNewFooRow ()
public class FooDataTable
{
// -- Other implementation
public FooRow MyNewFooRow()
{
FooRow fr = this.NewFooRow(); // call the original factory
fr.RegisterEvents();
return fr;
}
}
et utilisez cette nouvelle usine où que vous utilisiez l’ancienne ...