Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
In my Winforms application I am trying to use `SqlDependency` so I created this data access class:
C#
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;
        }
    }

And I use it like this
C#
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);
        }
    }

In my Winforms, I call `GetWeldingPaintProduction` method on form shown event like this
C#
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.");
    }

The `OnDependencyChange` is never being hit.
I have already enabled the service broker.
This is my stored procedure:
SQL
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

I try with insert, update and delete. In the database no queues are found.
What I am missing?
XML
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.1" />


What I have tried:

There are no ideas left in my head
Posted
Updated 21-Jul-23 6:02am
Comments
Graeme_Grant 14-Jul-23 5:20am    
[moved]

You wire it up here:
if (onChangeEventHandler != null)
{
	var sqlDependency = new SqlDependency(sqlCommand);
	sqlDependency.OnChange += onChangeEventHandler;
}

The issue I think is scope. The scope only exists in the if statement.
 
Share this answer
 
Comments
Mahfoud Bouabdallah 2022 14-Jul-23 6:05am    
Hello Graeme Grant,
In the first load of the form or in click of button BtnRefresh it is hit the
if (onChangeEventHandler != null)
{
var sqlDependency = new SqlDependency(sqlCommand);
sqlDependency.OnChange += onChangeEventHandler;
}

And subscribe sqlDependency.OnChange
Graeme_Grant 14-Jul-23 9:42am    
The scope of the sqlDependency variable only exists for the execution of the If { .. } block. you need to move it so the event can be caught.
Mahfoud Bouabdallah 2022 15-Jul-23 11:15am    
I remove the if statement so the code will be like this
var sqlDependency = new SqlDependency(sqlCommand);
sqlDependency.OnChange += onChangeEventHandler;

Still nothing happened and no queues have been registered in the database.
Graeme_Grant 15-Jul-23 20:18pm    
I notice that you deleted your post saying that it still is not working. Did you figure out your issue and that is why you deleted it?
Mahfoud Bouabdallah 16-Jul-23 13:20pm    
No the problem not solved yet. The deleted post It's the same as my last comment. Sorry for the inconvenience
I made this change to the database
SQL
ALTER AUTHORIZATION ON DATABASE::SIM TO sa;

the previews owner (MYLIFE\MBoua) has (sysadmin and public) roles and windows authentication
The (sa) has the same roles (sysadmin and public) with sql authentication.
Which is strange to me. Could the authentication type make this difference?
I have also changed the connection string to be like this
Server=(localdb)\\MSSQLLocalDB;Database=SIM;user id=sa;password=PassWord;Encrypt=False
 
Share this answer
 
Comments
Graeme_Grant 21-Jul-23 12:06pm    
This is not a solution. You need to Improve the question. Use Improve question link on the question itself.
Richard Deeming 24-Jul-23 8:22am    
Your application should NEVER connect to the database as the sa user. That's an unrestricted user, which could be used to destroy your database, your server, or even your entire network.

Connect as a specific user which has only the permissions required by your application.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900