public void CheckForAndPublishChanges()
        {
            var allChangeRecords = new Dictionary <string, OutboxCDCRecord>();
            var orderedChanges   = new List <string>();

            RunStoredProcedure("dbo.GetCDCUpdates", reader =>
            {
                while (reader.Read())
                {
                    var record = new CustomerCDCRecord(reader);
                    if (!allChangeRecords.ContainsKey(record.LSNString))
                    {
                        allChangeRecords.Add(record.LSNString, record);
                    }
                    else
                    {
                        CustomerCDCRecord.Update(reader, ref record);
                    }
                }


                reader.NextResult();

                while (reader.Read())
                {
                    orderedChanges.Add(Convert.ToBase64String((byte[])reader.GetValue(0)));
                }
            });

            var sentMessages = new DataTable
            {
                Columns =
                {
                    new DataColumn("ChangeId",     typeof(long)),
                    new DataColumn("EventSentUTC", typeof(DateTimeOffset))
                }
            };

            foreach (var lsn in orderedChanges)
            {
                var changeRecord = allChangeRecords[lsn];

                if (changeRecord is CustomerCDCRecord customerCDC)
                {
                    SendCustomerCDCEvent(customerCDC);
                    sentMessages.Rows.Add(changeRecord.ChangeId, DateTimeOffset.UtcNow);
                }
            }

            //Store the record in outbox postmarks
            if (sentMessages.Rows.Count > 0)
            {
                RunStoredProcedure("dbo.UpdateOutboxEventSentTimeStamp", null,
                                   new Dictionary <string, object> {
                    { "@postmarks", sentMessages }
                });
            }
        }
 private static CustomerCDCEvent GetCustomerProperties(CustomerCDCRecord cdc)
 {
     return(new CustomerCDCEvent
     {
         FirstName = cdc.FirstName,
         LastName = cdc.LastName,
         Address = cdc.Address,
         State = cdc.State,
         City = cdc.City,
         Country = cdc.Country,
         CorrelationId = Guid.NewGuid().ToString()
     });
 }
        private void SendCustomerCDCEvent(CustomerCDCRecord cdc)
        {
            var customerEvent = default(CustomerNotificationEvent);

            switch (cdc.Operation)
            {
            case CDCOperation.Delete:
                customerEvent = new CustomerNotificationEvent
                {
                    CDCEventType  = CDCEventTypeEnum.Delete,
                    CustomerEvent = GetCustomerProperties(cdc)
                };
                break;

            case CDCOperation.Insert:
                customerEvent = new CustomerNotificationEvent
                {
                    CDCEventType  = CDCEventTypeEnum.Insert,
                    CustomerEvent = GetCustomerProperties(cdc)
                };
                break;

            case CDCOperation.UpdateBeforeChange:
                break;

            case CDCOperation.UpdateAfterChange:
            case CDCOperation.Upsert:

                customerEvent = new CustomerNotificationEvent
                {
                    CDCEventType  = CDCEventTypeEnum.Upsert,
                    CustomerEvent = GetCustomerProperties(cdc)
                };
                break;
            }

            // publish Event
            if (customerEvent != default(CustomerNotificationEvent))
            {
                var args = new CustomerCDCEventArgs <CustomerNotificationEvent>(customerEvent);
                HandleCustomerNotificationEvent?.Invoke(this, args);
            }
        }