Экземпляр sqldependency.OnChange, после обжига объект sqldatareader, но не возвращает данные
Когда я выполняю запрос с фильтром столбцов datetime
WHERE [Order].CreatedOn >= @CreatedOn
Используя SqlDependency, Изменение источника данных запускает событие SqlDependency.OnChange, но SqlDataReader, связанное сSqlCommand, не возвращает данные (reader.HasRows всегда возвращает false).
Когда я просто изменяю условие фильтра в моей инструкции SQL на
WHERE [Order].StatusId = 1"
Он просто работает нормально, и SqlDataReader возвращает данные (reader.HasRows возвращает true)
Код:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace SignalRServer
{
public partial class DepartmentScreen : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var u = System.Security.Principal.WindowsIdentity.GetCurrent().User;
var UserName = u.Translate(Type.GetType("System.Security.Principal.NTAccount")).Value;
CheckForNewOrders(DateTime.Now);
}
private void CheckForNewOrders(DateTime dt)
{
string json = null;
string conStr = ConfigurationManager.ConnectionStrings["connString"].ConnectionString;
using (SqlConnection connection = new SqlConnection(conStr))
{
string query = string.Format(@"
SELECT [Order].OrderId
FROM [dbo].[Order]
WHERE [Order].CreatedOn >= @CreatedOn");
// query = string.Format(@"
// SELECT [Order].OrderId
// FROM [dbo].[Order]
// WHERE [Order].StatusId = 1");
using (SqlCommand command = new SqlCommand(query, connection))
{
command.Parameters.Add("@CreatedOn", SqlDbType.DateTime);
command.Parameters["@CreatedOn"].Value = DateTime.Now;
command.Notification = null;
SqlDependency dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
json = reader[0].ToString();
}
}
}
SignalRHub hub = new SignalRHub();
hub.OrderReceived(json, null);
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change)
{
CheckForNewOrders(DateTime.Now);
}
else
{
//Do somthing here
//Console.WriteLine(e.Type);
}
}
}
}
Изображения:
2 ответов:
При передаче DateTime.Теперь в качестве контрольной даты вы вряд ли получите записи, которые были созданы в какой-то момент времени (за исключением случаев, когда записи создаются в будущем, и поэтому у вас есть некоторые проблемы со временем сервера или имя столбца "createdOn" очень пропущено).
Чтобы получить последние записи, основанные на некоторой дате обновления, вам нужно сделать что-то вроде этого:
- создайте глобальную переменную, которая сохраняет максимальную созданную дату, которую вы иметь уже извлечен (
_refDateв моем примере, инициализирован в значение ты выбираешь дату и время.MinValue в моем случае, чтобы получить все записи в первом вызове, а затем получить их только постепенно, вы также можете взять DateTime.Теперь, чтобы начать в один момент времени)- запуск запроса CheckForNewOrders
- при получении результатов также отправьте столбец CreatedOn и сохраните максимальную полученную дату CreatedOn в качестве новой контрольной даты
- при изменении значения в БД и событии
dependency_OnChangegets triggered вам нужно запустить запрос с последним значением_refDate, чтобы получить все, что вы еще не получили- снова обновите значение
_refDateи так далее ..Не тестируется, но это должно работать (позаботьтесь о _refDate, чтобы быть доступным глобально)
public partial class DepartmentScreen : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { var u = System.Security.Principal.WindowsIdentity.GetCurrent().User; var UserName = u.Translate(Type.GetType("System.Security.Principal.NTAccount")).Value; CheckForNewOrders(_refDate); } private DateTime _refDate = DateTime.MinValue; private void CheckForNewOrders(DateTime dt) { string json = null; string conStr = ConfigurationManager.ConnectionStrings["connString"].ConnectionString; using (SqlConnection connection = new SqlConnection(conStr)) { string query = string.Format(@" SELECT [Order].OrderId, [Order].CreatedOn FROM [dbo].[Order] WHERE [Order].CreatedOn >= @CreatedOn"); // query = string.Format(@" // SELECT [Order].OrderId // FROM [dbo].[Order] // WHERE [Order].StatusId = 1"); using (SqlCommand command = new SqlCommand(query, connection)) { command.Parameters.Add("@CreatedOn", SqlDbType.DateTime); command.Parameters["@CreatedOn"].Value = dt; command.Notification = null; SqlDependency dependency = new SqlDependency(command); dependency.OnChange += new OnChangeEventHandler(dependency_OnChange); connection.Open(); SqlDataReader reader = command.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { //json = reader[0].ToString(); var date = Convert.ToDateTime(reader["CreatedOn"]); if (date > _refDate) { _refDate = date; } } } } } //SignalRHub hub = new SignalRHub(); //hub.OrderReceived(json, null); } private void dependency_OnChange(object sender, SqlNotificationEventArgs e) { if (e.Type == SqlNotificationType.Change) { CheckForNewOrders(_refDate); } else { //Do somthing here //Console.WriteLine(e.Type); } } } }
Когда метод
CheckForNewOrdersвызывается из событияonchangecommand.Parameters.Add("@CreatedOn", SqlDbType.DateTime); command.Parameters["@CreatedOn"].Value = DateTime.Now;Для параметра
@CreatedOnВы передаетеDateTime.Now(Не время его изменения). В базе данных не будет никаких данных, удовлетворяющих условию.





Comments