Created
June 23, 2017 05:44
-
-
Save Siliconrob/c3fdc2ec11253bbb8beba3d4f55bb7f7 to your computer and use it in GitHub Desktop.
SqlDependencyEx - TableListener Example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/****** Object: Table [dbo].[Table1] Script Date: 6/22/2017 10:42:23 PM ******/ | |
SET ANSI_NULLS ON | |
GO | |
SET QUOTED_IDENTIFIER ON | |
GO | |
CREATE TABLE [dbo].[Table1]( | |
[Id] [int] IDENTITY(1,1) NOT NULL, | |
[Description] [nchar](10) NULL, | |
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED | |
( | |
[Id] ASC | |
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] | |
) ON [PRIMARY] | |
GO | |
/****** Object: Table [dbo].[Table2] Script Date: 6/22/2017 10:42:23 PM ******/ | |
SET ANSI_NULLS ON | |
GO | |
SET QUOTED_IDENTIFIER ON | |
GO | |
CREATE TABLE [dbo].[Table2]( | |
[Id] [int] IDENTITY(1,1) NOT NULL, | |
[Description] [nchar](10) NULL, | |
CONSTRAINT [PK_Table2] PRIMARY KEY CLUSTERED | |
( | |
[Id] ASC | |
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] | |
) ON [PRIMARY] | |
GO | |
insert into table1 ([description]) values ('abc') | |
insert into table2 ([description]) values ('def') | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Program | |
{ | |
private const string Connection = "Data Source=(local);Initial Catalog=master;Integrated Security=True"; | |
private const string Database = "TestDatabase"; | |
private static void Main(string[] args) | |
{ | |
var listener = TableUpdateListener("Table1", 1, FirstTableUpdated); | |
var listener2 = TableUpdateListener("Table2", 2, SecondTableUpdated); | |
listener.Start(); | |
listener2.Start(); | |
Console.WriteLine("______________Escuchando_______________"); | |
Console.ReadKey(); | |
listener.Stop(); | |
listener2.Stop(); | |
} | |
private static SqlDependencyEx TableUpdateListener(string tableName, int identity, EventHandler<TableChangedEventArgs> handler) | |
{ | |
var listener = new SqlDependencyEx( | |
Connection, | |
Database, | |
tableName, | |
listenerType: NotificationTypes.Update, | |
identity: identity); | |
listener.TableChanged += handler; | |
return listener; | |
} | |
private static void SecondTableUpdated(object o, SqlDependencyEx.TableChangedEventArgs e) | |
{ | |
Console.WriteLine($"SecondTableUpdated {e.Data}"); | |
} | |
private static void FirstTableUpdated(object o, SqlDependencyEx.TableChangedEventArgs e) | |
{ | |
Console.WriteLine($"FirstTableUpdated {e.Data}"); | |
} | |
} |
This is considered as a bad practice to use SqlDependencyEx as a root for Client-Server applications. A good solution here would be to have only 1 listener per table and place it in a service which shares events with clients via other protocols like WCF/WebSockets etc. See working best practices here and here.
I would agree that sharing events from the say a console application or a windows service through other events will make your application
- Easier to understand
- Debug
- Composable
- Testable
I wouldn't recommend WCF as it is so complicated every time I try to debug it. WebSockets yes and Server Sent Events in ServiceStack as an example are in my experience easier to understand and readily cross platform.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks a lot man. working great now. i am going to send u my class that i use as upper layer to access to ur code. that will be a suggestion to add new funtionalities to ur code if that is fine to u.
as i am workig with a client where i have to install many window services listening different tables. so every time i create a new litener i have to consult db to check how many listeners r aded before to give a new number not repeated to new litener. well to avoid that i created a new class as upper layer to acces ur litener and also change type of return XML to an EF entity. this is just an idea. thanks for ur help. My appriciations. thanks again
DbListener.cs
public class DbListener
{
public string conexion { get; private set; }
public string dbName { get; private set; }
public string table { get; private set; }
public string SchemaName { get; private set; }
public NotificationTypes NotificaionTypes { get; private set; }
public bool DetailsIncluded { get; private set; }
public int Identity { get; private set; }
}
Program.cs
class Program
{
private static string conx = "Connection"; // is name of conx in config as using EF context
private static DbListener listener = null;
private static DbListener listener2 = null;
static void Main(string[] args)
{
try
{
listener = new DbListener(conx);
listener.Subscribe(Table: "Table1", NotifyTypes: "update");
listener.OnChange(OnChange_L1);
listener.Start();