我有一个与SQL Server数据库一起使用的C#程序。该设置应该通过LAN工作。
现在,如果我使用计算机A中的程序将值插入服务器,我将如何从计算机B中的程序自动读取该数据?
基本上,例如,如果我编辑文本字段并将内容保存到数据库,则另一个程序应该更新自己的文本字段以匹配主机的文本字段。
我的想法是每隔2秒左右通过一个计时器定期检查数据库。这种方法会出现性能问题吗?大多数时候我只需要一次读取1行,并且行的内容是简单的数字和字符串,没什么太大的。
还有其他方法吗?
先谢谢。
P.S。运行SQL Server 2005 Express和Visual Studio 2005,如果这意味着什么。
答案 0 :(得分:3)
您可以定期从计算机b检查数据库。将lastupdated datetime字段添加到行中,并且仅覆盖自上次应用程序在计算机b上运行以来已更新/插入的行。
在我看来,这更像是一个解耦的解决方案
答案 1 :(得分:2)
我认为您可以在表中存储上次更新时间。
这样你就可以得到一个廉价的池化查询(如果有新的更新,只需要进行切换,如果确实已经更改,则仅从数据库中检索实际数据)。
答案 2 :(得分:2)
正如评论中已经建议的那样,最好的办法是在给定的SqlCommand上使用SqlDependancy来等待任何更改。
答案 3 :(得分:1)
一旦插入表格,您就可以让计算机A向计算机B发送消息(通过套接字,远程处理等)。
答案 4 :(得分:1)
如果您担心性能问题,也许您只能在需要时检查数据是否已被修改(修改或显示)。
但是,如果您需要监控更改,那么无论何时进行更改,我都会建议计算机A向B发送消息...
答案 5 :(得分:1)
除了所有建议之外,您还可以构建一个基本的表监视器(注意这可能是错误的,我在大约15分钟内编写它,但应该给你这个想法)。我测试了插入和删除,显然它可以被改进以检测更新,具体取决于你想要获得的花哨程度。你可以创建自定义事件args等。另外我只是抛出System.Exceptions,因为它的概念证明。 / end免责声明
表观察者类:
public class TableWatcher
{
private string mDatabaseConnection;
private string 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(string databaseConnection, string 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();
string query = String.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;
}
}
用法:
string dbConn = "Data Source=localhost;Initial Catalog=Test;Integrated Security=SSPI;";
string 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);
从控制台应用运行: