2015-12-25 6 views
5

मेरे पास 2 अलग-अलग डेटाबेस कनेक्शन के साथ 2 अलग-अलग SQLDependencies का उपयोग करने के लिए परिदृश्य है, लेकिन एक फ़ंक्शन में कॉल करें।सी # में एक समारोह का उपयोग कर 2 अलग-अलग डेटाबेस के साथ एसक्लड निर्भरता और सिग्नलआर का उपयोग कैसे करें?

मैं एसक्यूएल पर निर्भरता का उपयोग करके पहली डीबी द्वारा अपडेट प्राप्त करना चाहता हूं, फिर दूसरे डीबी परिवर्तनों पर दूसरा डीबी सिंक करें, फिर दूसरे डीबी अपडेट पर मैं सिग्नल द्वारा क्लाइंट एंड केंडो ग्रिड में परिवर्तन लोड करना चाहता हूं, सरल प्रक्रिया काम कर रही है , लेकिन जब पहली बार डीबी 1 बदलता है तो यह डीबी 2 को सिंक करता है, फिर डीबी 2 क्लाइंट एंड पर परिवर्तन दिखाने के लिए सूचित करता है, लेकिन डीबी 1 में दूसरी बार परिवर्तन करते समय भी वही प्रक्रिया होती है, एसक्यूएल पर निर्भरता 3 बार कॉल करती है और क्लाइंट साइड 3 बार सूचित करती है, तीसरे बार में बदलाव के लिए DB1 अपने SqlDepency 6 समय या उससे अधिक कहता है, इसका मतलब यह है जब उसके SqlDependency पर इतना करने के लिए 3 के बाद अगले परिवर्तन अनंत समय कॉल:

  1. EmailHub (डीबी 2 हब)

    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 हब)

    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 (डीबी 2 समारोह)

    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. डीबी 2 SqlDependency

    private void dependencyemailmessage_OnChange(object sender, SqlNotificationEventArgs e) 
        { 
         if (e.Type == SqlNotificationType.Change) 
         { 
          EmailHub.UpdateRecords(); 
         } 
        } 
    
  5. HMailDB (DB1 एसक्यूएल समारोह)

    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. ग्राहक अंत कोड (केंडो ग्रिड) केंडो ग्रिड

    में

    <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 पद्धति उपयोग

मैंने अपनी समस्या को विस्तार से समझाया है। कृपया मुझे किसी भी वैकल्पिक अनुकूलित समाधान को हल करने या सुझाव देने के लिए मार्गदर्शन करें, मैं आपके मूल्यवान समय और प्रयास की सराहना करता हूं। धन्यवाद

उत्तर

0

मुझे SQL निर्भरता का उपयोग कर एक ही तरह की समस्याएं थीं।

इसलिए मैंने इसे प्रभावी ढंग से उपयोग करने के लिए एक कक्षा बनाई है।

नोट: यदि आप Application_Start पर SqlDependency.Start(_connStringDB1); बुलाना चाहिए (केवल एक बार)

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();  
    } 
} 

उपयोग

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 
}); 
संबंधित मुद्दे