在我的Winforms应用程序中,我试图使用SqlDependency
,所以我创建了这个数据访问类:
internal class DataAccessLayer
{
private readonly SqlConnection sqlconnection;
public DataAccessLayer()
{
sqlconnection = new SqlConnection(LoginUserDetails.Connection);
}
// Method to open the connection
public async Task Open()
{
if (sqlconnection.State != ConnectionState.Open)
{
await sqlconnection.OpenAsync().ConfigureAwait(false);
}
}
// Method to close the connection
public void Close()
{
if (sqlconnection.State == ConnectionState.Open)
{
sqlconnection.Close();
}
}
private void AddSqlCommandParameters(SqlCommand sqlcmd, string stored_procedure)
{
sqlcmd.CommandType = CommandType.StoredProcedure;
sqlcmd.CommandText = stored_procedure;
sqlcmd.Connection = sqlconnection;
}
// Method to read data from database
public async Task<DataTable> SelectDataAsync(string stored_procedure, SqlParameter[] param, OnChangeEventHandler onChangeEventHandler = null)
{
if (string.IsNullOrEmpty(stored_procedure))
{
return null;
}
await using var sqlCommand = new SqlCommand();
AddSqlCommandParameters(sqlCommand, stored_procedure);
if (param != null)
{
sqlCommand.Parameters.AddRange(param);
}
if (onChangeEventHandler != null)
{
var sqlDependency = new SqlDependency(sqlCommand);
sqlDependency.OnChange += onChangeEventHandler;
}
using DataTable dt = new();
using SqlDataAdapter da = new(sqlCommand);
await Task.Run(() => da.Fill(dt)).ConfigureAwait(false);
return dt;
}
}
字符串
而我是这样用的
internal class CLS_Welding
{
public static async Task<DataTable> GetWeldingPaintProduction(OnChangeEventHandler onChangeEventHandler = null)
{
using var DAL = new DataAccessLayer();
return await DAL.SelectDataAsync("GetWeldingPaintProduction", null, onChangeEventHandler).ConfigureAwait(false);
}
}
型
在我的Winforms中,我对窗体显示的事件调用GetWeldingPaintProduction
方法,如下所示
private async Task GetData()
{
GCBlack.DataSource = await ClsWelding.GetWeldingPaintProductionAsync(OnDependencyChange).ConfigureAwait(false);
}
private void OnDependencyChange(object sender, SqlNotificationEventArgs e)
{
// Refresh the data.
Invoke(new MethodInvoker(async delegate
{
await GetData().ConfigureAwait(false);
}));
// Notify the user that the data has changed.
MessageBox.Show("The Welding Paint Production data has changed.");
}
型OnDependencyChange
永远不会被击中。
我已经启用了Service Broker。
这是我的存储过程:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetWeldingPaintProduction]
AS
SELECT
daiPaiPro.[id],
[FK_idPartShip],
proinfo.ProjectN,
[Parts],
[Profile],
[Quantity],
[Qty] - [WeldingPaintQty] AS 'Reste Qté',
[Length],
[Surface],
ProShip.[Weight],
CAST(ProShip.[Weight] * [Quantity] AS decimal(18, 2)) AS 'Poids Tot',
[Designation],
[Note],
[CreationDate],
CONCAT(daiPaiPro.[UserID], ' ', emp.LastName_Employee, ' ', emp.FirstName_Employee) AS 'Utilisateur',
cust.Name AS 'Client',
ShiftTime.ShiftTime,
FK_ShiftTime,
FK_idNextProcess,
ProShip.Qty,
IdDailyWeldingProduction,
IdDailyPrefabrication,
SupBS.Structure
FROM
[dbo].[DailyWeldingPaintProduction] daiPaiPro
INNER JOIN
ProjectShipping ProShip ON ProShip.id = [FK_idPartShip]
INNER JOIN
ProjectInfo proinfo ON proinfo.id = ProShip.IdProject
INNER JOIN
Employee emp ON ID_Employee = daiPaiPro.[UserID]
INNER JOIN
Customer cust ON cust.ID = proinfo.FK_Customer
INNER JOIN
ShiftTime ON ShiftTime.id = FK_ShiftTime
LEFT JOIN
StructureType SupBS ON SupBS.id = FKSupBS
ORDER BY
[CreationDate] DESC
GO
型
我尝试插入、更新和删除。在数据库中未找到队列。
我错过了什么?
我正在使用Microsoft.Data.SqlClient
Version=“5.1.1”
2条答案
按热度按时间szqfcxe21#
我要感谢你们所有人帮助我解决这个问题
我对数据库做了这个更改
字符串
预览所有者(MYLIFE\MBoua)具有(sysadmin和public)角色和Windows身份验证
(sa)与sql身份验证具有相同的角色(sysadmin和public)。
我觉得很奇怪。身份验证类型会造成这种差异吗?
我还将连接字符串更改为
型
unhi4e5o2#
SqlCommand参数
另一个堆栈溢出用户也有类似的问题,here你可以看到如何用
OnDependencyChange()
钩子执行一个函数。他们的解决办法是1.命令类型为
CommandType.StoredProcedure
他们在获取SQL依赖项之前放置
command.CommandType = CommandType.StoredProcedure;
。(看起来你已经做到了)。1.使用SQLConnection函数,并将存储过程名称和连接作为参数。
在您的情况下,应该将
await using var sqlCommand = new SqlCommand();
替换为await using var sqlCommand = new SqlCommand(stored_procedure, sqlconnection);
Service Broker
您的问题还可能是因为您的数据库不支持ServiceBroker,而ServiceBroker是SqlDependency工作所必需的。您可以使用以下SQL命令检查并启用此功能:
ALTER DATABASE <database_name> SET ENABLE_BROKER
这里有更多关于这个的信息。查询通知需求
代码无法工作的另一个原因是它没有权限。您可以执行what this user did,这里还有一个启用某些权限的示例。
希望这对你有帮助。