2015-12-25 9 views
5

2 farklı veritabanı bağlantısı olan 2 farklı SqlDependencies kullanmak için senaryo kullanıyorum, ancak tek bir işlev çağırın.SqlDependency ve SignalR, C# içindeki bir işlev kullanılarak 2 farklı veritabanında nasıl kullanılır?

Ben çalışıyor ben Signalr basit bir işlem ile müşteri uç Kendo Izgarasındaki değişiklikleri yüklemek istediğiniz 2 DB güncellemelerine öyleyse, o zaman, 1 DB değişiklikleri 2 DB senkronize SqlDependency kullanarak 1 DB tarafından güncelleştirmeleri almak istiyorum ancak, DB1 değiştikçe, DB1 değiştiğinde DB2'yi sonra da istemciye bildirir, aynı zamanda DB1'de 2. zaman değişikliklerini alırken aynı işlemi yapar, SqlDependency 3 kez çağırır ve istemci tarafında 3 kez bildirir. DB1 onun SqlDepency 6 defa veya daha fazla çağıran bir SqlDependency üzerinde çok 3 ila sonraki değişiklikler Sınırsız bir aradığında, ort

  1. EmailHub (DB2 Hub)

    public class EmailHub : Hub 
        { 
         private static string _connStringDB2 = ConfigurationManager.ConnectionStrings["MyDB2"].ToString(); 
    
         [HubMethodName("updateRecords")] 
         public static void UpdateRecords() 
         { 
          IHubContext context = GlobalHost.ConnectionManager.GetHubContext<EmailHub>(); 
          context.Clients.All.getUpdates(); 
         } 
    
        } 
    
  2. HMailHub (DB1 merkezi)

    public class HMailHub : Hub 
        { 
         private static string _connStringDB1 = ConfigurationManager.ConnectionStrings["MyDB1"].ToString(); 
    
         [HubMethodName("updateRecords")] 
         public static void UpdateRecords() 
         { 
          IHubContext context = GlobalHost.ConnectionManager.GetHubContext<EmailHub>(); 
          context.Clients.All.getUpdates(); 
         } 
    
        } 
    
  3. GetEmailMessagesSQL (DB2 fonksiyonu)

    public IEnumerable<EmailAflAwmMessageDM> GetEmailMessagesByAccountSQL(string emailid) 
        { 
         var messages = new List<EmailAflAwmMessageDM>(); 
    
         // sync hmailDb to LocalDb by EmailAccountId 
         HMailServerSync objEmailSync = new HMailServerSync(); 
         objEmailSync.GetEmailMessagesByAccount(Guid.Parse(emailid)); 
    
         // stop all Sql dependencies before start new one 
         SqlDependency.Stop(_connStringDB1); 
         SqlDependency.Stop(_connStringDB2); 
    
         //hmailDB service(DB1 sql function call) 
         hmailsyncService(emailid); 
    
         using (var connection = new SqlConnection(_connString)) 
         { 
          connection.Open(); 
          using (var command = new SqlCommand(SQL.emailmessagesbyaccount_sql(), connection)) 
          { 
           command.Parameters.Add(new SqlParameter("@emailaccountid", emailid)); 
           command.Notification = null; 
           var dependency = (dynamic)null; 
           SqlDependency.Start(_connStringDB2); 
           dependency = new SqlDependency(command); 
           dependency.OnChange += new OnChangeEventHandler(dependencyemailmessage_OnChange); 
           if (connection.State == ConnectionState.Closed) 
            connection.Open(); 
           using (var reader = command.ExecuteReader()) 
            messages = reader.Cast<IDataRecord>() 
             .Select(x => new EmailAflAwmMessageDM() 
             { 
              to_msg = x.GetString(0), 
              from_msg = x.GetString(1), 
              subject = x.GetString(2), 
              msg_date = x.GetDateTime(3) 
    
             }).ToList(); 
          } 
          connection.Close(); 
    
         } 
         return messages; 
        } 
    
  4. DB2 SqlDependency

    private void dependencyemailmessage_OnChange(object sender, SqlNotificationEventArgs e) 
        { 
         if (e.Type == SqlNotificationType.Change) 
         { 
          EmailHub.UpdateRecords(); 
         } 
        } 
    
  5. HMailDB (DB1, SQL fonksiyonu)

    public void GetHmailMessagesByAccountSQL(int hmailid) 
    { 
        using (var connection = new SqlConnection(_connStringDB1)) 
        { 
         connection.Open(); 
         using (var command = new SqlCommand(SQL.hmailmessages_sql(), connection)) 
         { 
          command.Parameters.Add(new SqlParameter("@messageaccountid", hmailid)); 
          command.Notification = null; 
          var dependency = (dynamic)null; 
          SqlDependency.Start(_connStringDB1); 
          dependency = new SqlDependency(command); 
          dependency.OnChange += new OnChangeEventHandler(dependencyhmailmessage_OnChange); 
          if (connection.State == ConnectionState.Closed) 
           connection.Open(); 
          var reader = command.ExecuteReader(); 
         } 
         connection.Close(); 
        } 
    
    } 
    
  6. DB1 SqlDependency

    private void dependencyhmailmessage_OnChange(object sender, SqlNotificationEventArgs e) 
        { 
         if (e.Type == SqlNotificationType.Change) 
         { 
          EmailHub.UpdateRecords(); 
         } 
        } 
    
  7. Müşteri son kodu (Kendo Izgara) Kendo Izgara

    içinde

    <div id="grid"> 
        </div> 
    
        @Scripts.Render("~/bundles/signalr") 
        <script src="~/signalr/hubs"></script> 
    
        <script type="text/javascript"> 
        var emailid = '@TempData["DefaultEmailId"]' 
        $(function() { 
        // Declare a proxy to reference the hub. 
        var notifications = $.connection.emailHub; 
        // Create a function that the hub can call to broadcast messages. 
        notifications.client.getUpdates = function() { 
         alert("notification called"); 
         updateGridData(); 
        }; 
    
        // Start the connection. 
        $.connection.hub.start().done(function() { 
         alert("connection started") 
         updateGridData(); 
        }).fail(function (e) { 
         alert(e); 
        }); 
    
        function updateGridData() { 
         datasource = new kendo.data.DataSource({ 
          transport: { 
           read: 
            { 
             url: crudServiceBaseUrl + "EmailAflAwmMessage/getMessages/?emailid=" + emailid, 
             dataType: "json", 
            }, 
           update: 
            { 
             url: crudServiceBaseUrl + "EmailAflAwmMessage/Put/", 
             type: "PUT", 
             parameterMap: function (options, operation) { 
              if (operation !== "read" && options.models) { 
               return { 
                models: kendo.stringify(options.models) 
               }; 
              } 
             } 
            }, 
          }, 
          schema: 
           { 
            model: 
             { 
              id: "EmailMessageId", 
              fields: { 
               EmailMessageId: { editable: true, nullable: false, type: "guid" }, 
               subject: { editable: true, nullable: true, type: "string" }, 
               to_msg: { editable: true, nullable: false, type: "string" }, 
              } 
    
             } 
           } 
         }); 
    
         $("#grid").kendoGrid({ 
          dataSource: datasource, 
          editable: "popup", 
          toolbar: ["create"], 
          columns: [ 
          { 
           field: "to_msg", 
           title: "to_msg", 
          }, 
          { 
           field: "from_msg", 
           title: "from_msg", 
          }, 
          { 
           field: "subject", 
           title: "subject", 
          }, 
          { 
           field: "msg_date", 
           title: "msg_date", 
          } 
          ], 
          height: "400px", 
          pageable: { 
           refresh: true, 
           pageSizes: true, 
           buttonCount: 5 
          }, 
         }).data("kendoGrid"); 
        } 
    
    }); 
    

  8. API yöntemi kullanımı

Sorunumu yukarıda ayrıntılı olarak açıkladım. Lütfen herhangi bir alternatif optimize edilmiş çözümü önermek veya çözmek için bana yardımcı olun, değerli zamanınızı ve çabalarınızı takdir ediyorum. Teşekkürler

cevap

0

SQL Dependency kullanarak aynı tür sorunlarla karşılaştım.

Bu yüzden etkili bir şekilde kullanmak için bir sınıf oluşturdum.

Not:

public class LiveData 
{ 
    public string SprocOrQuery { get; set; } 
    private Dictionary<string, object> par = new Dictionary<string, object>(); 
    public Dictionary<string, object> Parameters { get { return par; } set { par = value; } } 
    public string SqlConn { get; set; } 
    public Action<DataTable> ActionOnData { get; private set; } 
    public bool EffectedOnly { get; set; } 
    public DateTime EffectDate = DateTime.Now; 
    public int EffectedCyles { get; private set; } 
    public DataTable Data { get; private set; } 
    public List<SqlNotificationInfo> Events { get; set; } 
    public SqlNotificationInfo CurrentEvent { get; private set; } 

    public LiveData() { } 
    public LiveData(string sprocOrQuery, Dictionary<string, object> parameters = null, string connection = null) 
    { 
     SprocOrQuery = sprocOrQuery; 
     Parameters = parameters; 
     SqlConn = connection; 
    } 

    public Task Start(Action<DataTable> actionOnData = null) 
    { 
     return Task.Factory.StartNew(() => 
     { 
      try 
      { 
       if (ActionOnData == null) ActionOnData = actionOnData; 
       SqlConnection sqlConn = new SqlConnection(SqlConn); 
       using (SqlCommand cmd = new SqlCommand(SprocOrQuery, sqlConn) { CommandType = SprocOrQuery.Contains(" ") ? CommandType.Text : CommandType.StoredProcedure, CommandTimeout = 60 }) 
       { 
        if (Parameters != null && Parameters.Count > 0) 
         foreach (var key in Parameters.Keys) cmd.Parameters.Add(new SqlParameter(key, Parameters[key])); 
        if (EffectedOnly) /* Sproc or Query must accept @UpdateDate parameter as DateTime */ 
        { 
         if (cmd.Parameters.Contains("EffectDate")) cmd.Parameters["EffectDate"].Value = EffectDate; 
         else cmd.Parameters.Add(new SqlParameter("EffectDate", EffectDate)); 
        } 
        cmd.Notification = null; 
        Data = new DataTable(); 
        new SqlDependency(cmd).OnChange += OnChange; 
        if (sqlConn.State == ConnectionState.Closed) sqlConn.Open(); 
        Data.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection)); 
       } 
       if ((Events == null || Events.Contains(CurrentEvent))) 
       { 
        if (EffectedCyles > 0) EffectDate = DateTime.Now; 
        EffectedCyles++; 
        if (ActionOnData != null) ActionOnData.Invoke(Data); 
       } 
      } 
      catch (Exception ex) 
      { 
       Logger.LogException(ex); 
      } 
     }); 
    } 

    private void OnChange(object sender, SqlNotificationEventArgs e) 
    { 
     CurrentEvent = e.Info; 
     SqlDependency dependency = sender as SqlDependency; 
     dependency.OnChange -= OnChange; 
     Start();  
    } 
} 

kullanımı (yalnızca bir kez) Application_Start de SqlDependency.Start(_connStringDB1); çağırmalıdır

new LiveData() 
{ 
    SprocOrQuery = @"SELECT 
         t.[ID], 
         t.[CreateDate], 
         t.[UpdateDate] 
        FROM 
         dbo.Table t 
         INNER JOIN dbo.Group g 
          ON g.[ID] = t.[GroupID] 
        WHERE 
         t.[UpdateDate] >= @EffectDate", 
    SqlConn = "SqlConnectionString", 
    EffectedOnly = true, 
    Events = new List<SqlNotificationInfo>() { SqlNotificationInfo.Update } 
}.Start(dt => 
{ 
    /* dt is the dataTable you get for every update */ 
    // you can run your dependencyemailmessage_OnChange logic here 
}); 
İlgili konular