c# - 在 .NET 7 和 WinForms 应用程序中使用 SqlDependency

标签 c# winforms stored-procedures sql-server-2019 sqldependency

在我的 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 永远不会被命中。

我已经启用了服务代理。

这是我的存储过程:

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版本=“5.1.1”

最佳答案

感谢大家帮助我解决这个问题
我对数据库进行了此更改

ALTER AUTHORIZATION ON DATABASE::SIM TO sa;

预览所有者 (MYLIFE\MBoua) 具有(系统管理员和公共(public))角色和 Windows 身份验证
(sa) 具有相同的角色(sysadmin 和 public),并具有 sql 身份验证。
这对我来说很奇怪。身份验证类型会造成这种差异吗?
我还将连接字符串更改为这样

Server=(localdb)\\MSSQLLocalDB;Database=SIM;user id=sa;password=PassWord;Encrypt=False 

关于c# - 在 .NET 7 和 WinForms 应用程序中使用 SqlDependency,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76682460/

相关文章:

mysql - 将 MS-SQL Server 存储过程转换为 MySQL 查询

mysql - 井字游戏字段列表 MySQL 中的未知列 'i'

mysql - 查询获取订单量小于上一个订单量的客户列表

c# - 使用 Dapper 调用带有地理参数的 PostgreSQL 函数时出现 NotSupportedException

C# 将字符串编码结构发送至 C 库

c# - TreeNode 在 TreeView 未聚焦时选择了 BackColor

c# - 如何从运行时创建的控件中获取值

c# - .net 应用程序中的 jQuery 日历

c# - 如何使用反射获取继承属性的值?

vb.net - DateTimePicker控件不显示AM/PM