【发布时间】:2022-01-05 11:11:01
【问题描述】:
我在windows中创建了一个服务Worker服务,它定期连接到数据库并将表中的第一个最新行发送到API
但是如何让服务只发送同一行一次,然后等到下一个新的出现。
ID不能有相同的值,是否可以在已经发送的行!=dbResult[0]的dbResult[0](id)可以发送时创建条件?
我的部分代码:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
string connectionString = "User=SYSDBA;" +
"Password=masterkey;" +
"Database=test.DTB;" +
"DataSource=localhost;" +
"Port:3050";
FbConnection mConnection = new FbConnection(connectionString);
mConnection.Open();
FbTransaction mTransaction = mConnection.BeginTransaction();
string SQLCommandText = "select first 1 * from TABLE where NAME = 449 order by DATE desc ";
FbCommand mCommand = new FbCommand(SQLCommandText, mConnection, mTransaction);
FbDataReader mReader = mCommand.ExecuteReader();
if (mReader.Read())
{
var values = new object[mReader.FieldCount];
{
mReader.GetValues(values);
var dbResult = values.Distinct().ToArray();
var dbResults = (string.Join("|", dbResult));
var result = new
{
ID = dbResult[0],
NAME = dbResult[1],
DATE = dbResult[2],
};
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(result);
}
}
}
catch (Exception ex)
{
Log.Fatal(ex, "Problem reading the database.");
}
await Task.Delay(10000, stoppingToken);
}
}
}
在得到 Barr J
的好线索后更新protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
string connectionString = "User=SYSDBA;" +
"Password=masterkey;" +
"Database=test.DTB;" +
"DataSource=localhost;" +
"Port:3050";
FbConnection mConnection = new FbConnection(connectionString);
mConnection.Open();
FbTransaction mTransaction = mConnection.BeginTransaction();
string SQLCommandText = "select NAME, DATE from TABLE where NAME = 449 and ISSENT = 0";
FbCommand mCommand = new FbCommand(SQLCommandText, mConnection, mTransaction);
FbDataReader mReader = mCommand.ExecuteReader();
while (mReader.Read())
{
var values = new object[mReader.FieldCount];
{
mReader.GetValues(values);
var dbResult = values.Distinct().ToArray();
var dbResults = (string.Join("|", dbResult));
var result = new
{
ID = dbResult[0],
NAME = dbResult[1],
DATE = dbResult[2],
};
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(result);
using FbConnection UpdateConnection = new(connectionString);
UpdateConnection.Open();
FbCommand writeCommand = new("update TABLE set ISSENT = @isSentValue where ID= @idValue", UpdateConnection);
writeCommand.Parameters.Add("@isSentValue", 1);
writeCommand.Parameters.Add("@idValue", dbResult[0]);
writeCommand.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
Log.Fatal(ex, "Problem reading the database.");
}
await Task.Delay(10000, stoppingToken);
}
}
}
【问题讨论】:
-
你可以记住类字段中的最新id,并在选择中添加
id>latestId条件。 -
插入新记录时为什么不运行任务?
-
您是否打算向 API 发送任何新行?如果您只发送第一个新行,它可能会丢失一些数据。如果同时添加了 5 个新行会怎样?显然我不完全理解您的项目,但我建议在表中添加一个字段,作为一个标志,如果它已发送到 API,您可以将其设置为 true。当然,您不能使用 SELECT 语句更改标志,但您可能需要一个简单的存储过程来更新标志并同时为您提供数据。
-
有没有教程如何记住类字段中的最新ID?我认为这是实现我的目标的好方法。当最新的 id 被记住时,不需要只发送第一行。
-
由于您的代码每 10 秒运行一次,表中可能已插入大量新记录,您需要同步所有这些行[通过调用 API],因此在类级别您可以维护成员
Dictionary<int,int> prevIDset,那么您可以检查当前获得的 ID 与先前运行的存在,并且只发送那些新的,并清除该 prevIDset,用本次运行中发送的新 ID 填充它们。
标签: c# sql database service-worker