C # Comment lire datatables d'une database SQL Server dès qu'elles sont insérées?

J'ai un programme C # qui fonctionne avec une database SQL Server. La configuration est supposée fonctionner sur un LAN.

Maintenant, si j'insère une valeur dans le server en utilisant un programme de l'ordinateur A, comment est-ce que je lirais automatiquement ces données du programme dans l'ordinateur B?

Fondamentalement, si je, par exemple, éditer un champ de text et enregistré le contenu dans la database, l'autre programme devrait mettre à jour son propre champ de text pour correspondre à celui de l'hôte.

Mon idée était de vérifier périodiquement la database tous les … 2 secondes ou plus via une timer. Y aurait-il des problèmes de performance avec cette approche? La plupart du time, je n'ai besoin de lire qu'une seule ligne à la fois, et le contenu de la rangée est un simple nombre et des strings, rien de trop gros.

Y a-t-il d'autres approches à cela?

Merci d'avance.

PS Exécution de SQL Server 2005 Express et Visual Studio 2005, si cela signifie quelque chose.

Vous pouvez vérifier périodiquement la database à partir de l'ordinateur b. Ajoutez un champ date-heure mis à jour aux lignes et ne tirez que sur les lignes qui ont été mises à jour / insérées depuis la dernière exécution de l'application sur l'ordinateur b.

C'est beaucoup plus d'une solution découplée à mon avis

Je pense que vous pourriez avoir une table où vous avez enregistré la dernière mise à jour.

De cette façon, vous pourriez avoir une requête de pooling bon marché (juste cheching s'il y avait de nouvelles mises à jour, et seulement récupérer datatables réelles de la database si elle était en effet changée).

Comme déjà suggéré dans les commentaires, votre meilleur pari est probablement d'utiliser SqlDependancy sur un SqlCommand donné pour attendre les changements.

Vous pouvez requestr à l'ordinateur A d'envoyer un message (sur une socket, un access distant, etc.) à l'ordinateur B dès qu'une insertion est effectuée dans la table.

Si vous êtes inquiet au sujet de la performance, peut-être que vous pourriez seulement vérifier si datatables ont été modifiées quand vous en avez besoin (pour le modifier, ou pour l'afficher).

Cependant, si vous avez besoin de surveiller les changements, alors je suggère que l'ordinateur A envoie un message à B chaque fois qu'une modification est apscope …

En plus de toutes les suggestions, vous pouvez également build un observateur de table de base (Notez que c'est probablement bogué, je l'ai écrit en environ 15 minutes, mais je devrais vous donner l'idée). J'ai testé les insertions et les suppressions, évidemment il pourrait être affiné pour détecter les mises à jour en fonction de la fantaisie que vous voulez get. Vous pouvez créer des arguments d'events personnalisés, etc. Je lance simplement System.Exceptions parce que sa preuve de concept. / fin de non-responsabilité

Classe de Watcher de table:

public class TableWatcher { private ssortingng mDatabaseConnection; private ssortingng mTableName; private bool mInitialized = false; private double mWatchInterval = 10; private System.Timers.Timer mTableTimer; private int mInitialRowCount; private int mCurrentRowCount; private bool mIsWatching = false; public event EventHandler RowsAdded; public event EventHandler RowsDeleted; protected virtual void OnRowsAdded(EventArgs e) { if (RowsAdded != null) RowsAdded(this, e); } protected virtual void OnRowsDeleted(EventArgs e) { if (RowsDeleted != null) RowsDeleted(this, e); } public int InitialRowCount { get { return mInitialRowCount; } } public int CurrentRowCount { get { return mCurrentRowCount; } } public TableWatcher(ssortingng databaseConnection, ssortingng tableToWatch) { mDatabaseConnection = databaseConnection; mTableName = tableToWatch; } public void Initialize() { mInitialized = true; mInitialRowCount = GetCurrentRows(); mCurrentRowCount = mInitialRowCount; } public void StartWatching(double interval) { if (mInitialized == false) { throw new Exception("Table Watcher has not been initialized. Call Initialize() first."); } if (mIsWatching == true) { throw new Exception("Table Watcher is already watching. Call Stop Watching to terminate."); } if (interval == 0) { throw new Exception("Interval is invalid. Please specify a value greater than 0."); } else { mIsWatching = true; mWatchInterval = interval; mTableTimer = new System.Timers.Timer(mWatchInterval); mTableTimer.Enabled = true; mTableTimer.Elapsed += new System.Timers.ElapsedEventHandler(mTableTimer_Elapsed); } } void mTableTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { mTableTimer.Enabled = false; int rowCount = GetCurrentRows(); if (rowCount > CurrentRowCount) { OnRowsAdded(new EventArgs()); } else if (rowCount < CurrentRowCount) { OnRowsDeleted(new EventArgs()); } mCurrentRowCount = rowCount; mTableTimer.Enabled = true; } private int GetCurrentRows() { int currentRows = 0; using (SqlConnection conn = new SqlConnection(mDatabaseConnection)) { conn.Open(); ssortingng query = Ssortingng.Format("Select Count(*) from {0}", mTableName); using (SqlCommand cmd = new SqlCommand(query, conn)) { object rows = cmd.ExecuteScalar(); if (rows != null) { currentRows = Convert.ToInt32(rows); } } } return currentRows; } public void StopWatching() { mTableTimer.Enabled = false; mInitialized = false; mIsWatching = false; } } 

Usage:

 ssortingng dbConn = "Data Source=localhost;Initial Catalog=Test;Integrated Security=SSPI;"; ssortingng tableName = "TestTable"; TableWatcher t = new TableWatcher(dbConn, tableName); t.RowsAdded += new EventHandler(t_RowsAdded); t.RowsDeleted += new EventHandler(t_RowsDeleted); t.Initialize(); t.StartWatching(100); 

En cours d'exécution à partir d'une application de console:

entrez la description de l'image ici