UpdateDataSet Entreprise Library 3.1 DAAB

Résolu
Signaler
Messages postés
46
Date d'inscription
vendredi 5 novembre 2004
Statut
Membre
Dernière intervention
30 septembre 2010
-
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
-
Bonjour à Tous,

Pour profiter des Blocks d'applications que propose Entreprise Library 3.1 (Exception Policy, Logging Validation etc..) je pensais utiliser le DAAB (Data Access Application Block) qui est la 'brique' d'accès aux données de Ent Lib 3.1

Jusque là cela aurait pas etre exploitable ...Mais mon problème est que dans un même dataset j'utilise les DataRelations. Elles  permettent de maintenir une logique relationnelle entre les DataTables de ce Dataset ce qui est très utile lors de mise à jour de Row parente (génération de Primary Key par le SGBD puis cette PK est rafraichie sur le client...on  peut alors utilisée cette PK pour effectuer des mises à jour des Rows Enfants qui connaissent leurs parents grace à leur Foreign Key...

En résumé, les datarelations font perdurer les relations Parent / Enfant de deux DataTables même lorsque l'une d'elle est en train d'etre ajouté ou modifiés en Base...Une contrainte est que ces deux DataTables doivent etre dans un même DataSet car c'est lui qui contient les DataRelations...Ma configuration est maintenant posée, passons à la problématique..


J'aimerais donc exploiter la brique DAAB mais je m'apercois que tout est
trop automatiser , notamment aux niveaux de la mise à jour des données.
En effet un des problèmes est que les
Adapters utilisés (comme le DataAdapter qui est une classe mère de
TableAdapter ou de DBDataAdapter )
possèdent des arguments par défauts tels que



AcceptChangesDuringFill = true;


AcceptChangesDuringUpdate = true;



Ce qui réinitialise les états des rows à Unchanged dès la fin de la méthode Update() ou Fill()...


ils ne peuvent pas être surcharger avant l'appel de Updataset car le
DataAdapter est créé, utilisé puis détruit en interne de la fonction
UpdataDataset...voila un risque d'utiliser des outils 'pret à l'emploi'
car je souhaite gérer moi même la réinitialisation des RowState (à Unchanged).Je rappele que le décisionnel des Commands à executer est
déterminé par les RowStates
(Added, Modified etc) pour que l'adapter déclenche les Commands
correspondantes
(INSERT, UPDATE etc...). Ces méthodes sont traitées ligne par ligne
...
 

Mon souci est que je je passe mon dataset unique à la méthode  comme ceci : (db est une DataBase)

int rowsAffected = db.UpdateDataSet(dataset, DataTable.TableName, insertCommand, updateCommand, deleteCommand, txMgr.GetTransaction(db));

Les XCommand concerne une seule DataTable, et cette fonction doit mettre à jour seulement cette DataTable...Mais je constate que c'est TOUS les rowstates de toutes les Datatables de ce DataSet qui sont remis à Unchanged après l'appel de cette méthode...Or j'aimerais que les AcceptChanges soit lancée UNIQUEMENT sur la Datatable  concerné afin de préserver les états des rows des autres Tables..

Une solution serait de modifier les sources (Heureusement Open Source de Entreprise Library...mais je n'arrive pas à exploiter les Assembly regénérer )
c'est ce que j'ai tenté mais un erreur survient lors du premier appel des fonction de Ent Lib..
Impossible de charger le fichier ou l'assembly
'Microsoft.Practices.EnterpriseLibrary.Common, Version=3.1.0.0, Culture=neutral, PublicKeyToken=null' ou une de ses dépendances.
La définition trouvée du manifeste de l'assembly ne correspond pas à la référence de l'assembly. (Exception de HRESULT : 0x80131040)

Une autre solution est de copier le Dataset et d'effectuer la mise à jour de cette copie pour préserver les rowtates de l'original...mais cela fait il aussi une copie des données  ou seulement ou copie de l'architecture du dataset..

Dataset DStoUpdate = OriginalDS.GetChanges().copy();


int rowsAffected = db.UpdateDataSet(DStoUpdate, DataTable.TableName,
insertCommand, updateCommand, deleteCommand, txMgr.GetTransaction(db));

En esperant ne pas avoir été trop long sur l'énoncé, j'espère que cela vous aura été aussi instructif que moi...

BINOME de ECOSMOSE
Association ecologique d'actions de culture et d'Informations

7 réponses

Messages postés
46
Date d'inscription
vendredi 5 novembre 2004
Statut
Membre
Dernière intervention
30 septembre 2010

Bon ca y est j'ai trouvé...une erreur toute bête ....
Avant d'utiliser Entreprise Library, j'utilisais les TableAdapters et l'outils de génération de code de Visual Studio, le designer de DataSet pour la précédente Couche d'Accés aux DOnnées (DAL)

Or j'avais choisi de paramétrer les DataRelations avec des "règles d'acceptation et de rejet" en "cascade" pour des contraintes qui n'ont plus lieu d'etre...de ce fait dès qu'un AcceptChanges était lancé sur une DataRow Parente, AcceptsChanges était invoqué sur les enfant...et donc plus de rows à mettre à jour dans l'instruction suivante...ce code illustre bien mon besoin....
Database db = new SqlDatabase("Data Source=.;Initial Catalog=Test;Integrated Security=True");
DataSet ds = new DataSet();

db.LoadDataSet(CommandType.Text, "SELECT * FROM Customers", ds, new string[] { "Customers" });
db.LoadDataSet(CommandType.Text, "SELECT * FROM Orders", ds, new string[] { "Orders" });

ds.Tables[0].Rows[0]["Name"] = "John Doe";
ds.Tables[1].Rows[0]["Number"] = "99999";
DbCommand customersUpdateCommand db.GetSqlStringCommand("Update Customers Set Name @Name WHERE CustomerId = @CustomerId");
db.AddInParameter(customersUpdateCommand, "Name", DbType.String, "Name", DataRowVersion.Current);
db.AddInParameter(customersUpdateCommand, "CustomerId", DbType.Int32, "CustomerId", DataRowVersion.Current);
DbCommand ordersUpdateCommand db.GetSqlStringCommand("Update Orders Set Number @Number WHERE OrderId = @OrderId");
db.AddInParameter(ordersUpdateCommand, "Number", DbType.String, "Number", DataRowVersion.Current);
db.AddInParameter(ordersUpdateCommand, "OrderId", DbType.Int32, "OrderId", DataRowVersion.Current);

// Get Changes Before
DataTable customerChangesBefore = ds.Tables[0].GetChanges(DataRowState.Modified);
DataTable orderChangesBefore = ds.Tables[1].GetChanges(DataRowState.Modified);

db.UpdateDataSet(ds, "Customers", null, customersUpdateCommand, null, UpdateBehavior.Standard);

// Get Changes After Customer Update - Orders Still Has a Pending Change
DataTable customerChangesBetween = ds.Tables[0].GetChanges(DataRowState.Modified);
DataTable orderChangesBetween = ds.Tables[1].GetChanges(DataRowState.Modified);

db.UpdateDataSet(ds, "Orders", null, ordersUpdateCommand, null, UpdateBehavior.Standard);

// Get Changes After All Updates - DataTables are Null.
DataTable customerChangesAfter = ds.Tables[0].GetChanges(DataRowState.Modified);
DataTable orderChangesAfter = ds.Tables[1].GetChanges(DataRowState.Modified);

Un bon retour d'expérience sur la migration vers entreprise Library qui j'espère vous sera profitable....en espérant que personne fasse la même bourde que moi...
Messages postés
46
Date d'inscription
vendredi 5 novembre 2004
Statut
Membre
Dernière intervention
30 septembre 2010

Voici un lien CodePlex pour étayer un peu mon problème..

http://www.codeplex.com/entlibcontrib/Wiki/View.aspx?title=Extended%20SQL%20Data%20Access%20Block&referringTitle=Home

BINOME de ECOSMOSE
Association ecologique d'actions de culture et d'Informations
Messages postés
46
Date d'inscription
vendredi 5 novembre 2004
Statut
Membre
Dernière intervention
30 septembre 2010

Désolé J'ai découvert entre temps  Ent Lib Contrib qui est la commaunuté qui code ent lib contrib...la méthode UpdateDataset a été surchargé pour solutionner mon problème il y a peu de temps...elle peut maintenat utiliser une dataable et  un tableau de Rows, ce qui evite que la méthode DataSet.acceptChanges soit appelée...ce qui preserverais les Rowstates des autres DataTables comme je le voudrais..

http://www.codeplex.com/entlibcontrib/SourceControl/ListDownloadableCommits.aspx

je vais donc installé la solution puis faire un retour..

BINOME de ECOSMOSE
Association ecologique d'actions de culture et d'Informations
Messages postés
46
Date d'inscription
vendredi 5 novembre 2004
Statut
Membre
Dernière intervention
30 septembre 2010

Non finalement, j'ai un souci lorsque je passe une DataTable (incluse dans un DataSet) à cette méthode, tous les RowState de TOUTES les dattables de ce DataSet redeviennent Unchanged après la mise à jour de la seule DataTable que je passe en argument...je ne peux pas isoler la Datatable de ce DataSet car je souhaite conserver la Datarelation qui la lie aux autres DataTables de ce Dataset...

Quelqu'un a une idée ou sait si en faisant un Dataset.copy(), les données des datatables sont MAJ ou faut il faire un Merge (Du coup les Perfs s'écrouleraient).....

BINOME de ECOSMOSE
Association ecologique d'actions de culture et d'Informations
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
98
Salut,

Ha tiens pas bête, il faudra que je pense à ça à l'occasion.
Merci du retour.

/*
coq
MVP Visual C#
CoqBlog
*/
Messages postés
46
Date d'inscription
vendredi 5 novembre 2004
Statut
Membre
Dernière intervention
30 septembre 2010

Cependant mes recherches ont soulevés un souci au niveau de la maitrise du comportement de l'acceptchanges()...
les attributs de l'Adapter utilisé par DAAB ont ces valeurs par défaut :
AcceptChangesDuringFill = true;
AcceptChangesDuringUpdate = true;

Après l'execution de UpdateDataset , AcceptsChanges est executer automatiquement donc si on veut exploiter le résumé des changements à effectuer en Base de données, il faut copier les rows destinées à etre traitées comme ceci :

dt = MydatatabletoUpdate.Getchanges(); //copy of the Rows which will be updated
SqlExDatabase.Updatedataset( MydatatabletoUpdate., DBcommands, etc...)

Displays
(dt);//car  MydatatabletoUpdate.Getchanges() == null à ce moment là.....

On pourrait titiller le fait que l'on ne peut pas garder les Rowstate car DAAB occulte (couvre) le paramétrage de l'adapter...(la méthode GetAdapter est private et donc pas surchargeable (pas de override possible)
Que pensez vous de cette redondance de données dans ce souci d'optimisation ?

BINOME de ECOSMOSE
Association ecologique d'actions de culture et d'Informations
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
98
Hmmm j'avoue que moi et les DataSets ça fait deux :p
C'est surtout le coup de la migration qui m'a intéressé, car ça c'est du domaine du fortement probable, .NET 1.1 arrivant petit à petit en fin de vie.

/*
coq
MVP Visual C#
CoqBlog
*/