0

我有一个使用 SQLDependency 的应用程序。我想在插入新行时向用户显示插入数据库表的最新行。

当我的查询是一个简单的选择语句时,这可以按预期工作,但是鉴于我想显示最近插入的行,我将查询编写为SELECT TOP语句。这导致了多个异常。在查看这个问题后,我了解到这TOP对 SQLDependency 无效,因此我将不得不找到其他解决方案。

这让我想知道两件事:

A) SQLDependency 不支持TOP表达式的原因是什么?

B)我想出的解决方案是根据 id 对结果进行排序并只显示最后一个。这工作正常,但我的表目前只有很少的行。我正在使用数据集,所以我预计一旦插入更多行,它就会减慢 - 这就是为什么我想将查询限制为仅最近的行。有一个更好的方法吗?

4

2 回答 2

5

本文解释了查询通知技术如何利用索引视图技术,因此它具有相同的限制。为了创建高效的索引视图,必须能够仅从当前更新中更新索引,而无需查看表中的任何其他行。如果 TOP 被允许,那么百万美元的问题是:如果您删除 TOP 中的一行,哪一行应该代替它?回答这个问题需要在表中搜索现在应该包含在 TOP 索引视图中的另一行,而不是已删除的行。因此,包含 TOP 的索引视图(或者,就此而言,存在同样问题的 MAX 或 MIN)不能有效地维护并且不允许。

可以通过查询来检测插入了一行COUNT_BIG(*)。一旦通知您计数已更改,查询新插入的行就很简单了。您还将收到有关 DELETES 的通知(即误报)。

于 2012-09-12T19:54:03.887 回答
0

@Remus Rusanu 解释得很好。您不能使用TOPSQL 命令的关键字。但是,如果你想选择一些TOP数据,你可以使用下面的替代解决方案。

我正在从数据库中选择所有记录,但我只在我的列表中放入了十条记录,并且我将此列表返回到我的仪表板。所以,每次我收到最新的十条记录。

TOP您可以在没有关键字的情况下使用当前的 SQL 命令。我的是:

SQL 命令:

Select [Id], [Name] FROM dbo.CUSTOMER where InsertDate = @InsertDate ORDER BY [ID] DESC;

然后,在您的应用程序中,您可以根据您的最高计数填写您的列表。
检查我对以下源代码的评论。

public List<CustomerModel> GetAllCustomer()
        {
            List<CustomerModel> lstCustomerModel = new List<CustomerModel>();
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                conn.Open();
                string InsertDate = string.Empty;
                InsertDate = DateTime.Now.ToString("yyyyMMdd");

                string query = "SELECT [Id] " +
                                    ",[Name] " +
                                "FROM [dbo].[Customer] where InsertDate = " + InsertDate + "   ORDER BY [Id] DESC;";
                SqlCommand cmd = new SqlCommand(query, conn);
                cmd.CommandType = CommandType.Text;
                cmd.Notification = null;
                SqlDependency.Stop(connectionString);
                SqlDependency.Start(connectionString);
                SqlDependency sqlDependency = new SqlDependency(cmd);
                sqlDependency.OnChange += OnDependencyChange;

                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    if (reader.HasRows)
                    {
                        int counter = 0;
                        while (reader.Read())
                        {
                            if (counter == 10) /* Here, I am reading just first ten record. After 10 records, I am not filling my List. So, It is kind of top 10 records.. Alternative solution.*/
                                break;
                            counter++;
                            
                            lstCustomerModel.Add(new CustomerModel
                            {
                               Id = Convert.ToInt32(reader.GetValue("Id")),
                               Name = WeightUnit = reader.GetValue("Name")
                            });

                            //break;
                        }
                    }
                }
            }

            return lstCustomerModel;
        }

        private void OnDependencyChange(object sender, SqlNotificationEventArgs e)
        {
            if (e.Type == SqlNotificationType.Change)
            {
                _context.Clients.All.SendAsync("refreshCustomers");
            }
        }
于 2020-08-04T22:32:47.210 回答