如何在Controller中使用带有.Net Core的SqlDependencyEx

时间:2017-11-28 23:51:07

标签: c# .net asp.net-core asp.net-core-signalr sqldependencyex

我今天花了很多钱试图让SqlDependencyEx在我的网站上使用signalR Core。我想监视数据库表中的更改,然后通过signalR更新站点上的数字以及特定查询的计数。

然而,虽然一切正常但我不确定我是否在我的控制器内正确使用SqlDependencyEx。这是第一次在C#中进行MVC项目,我发现了有限的如何实现它的例子。即使是SqlDependencyEx的GitHub页面也没有用,因为网站项目使用了表库的模拟。这就是我设置的内容:

在ConfigureServices

services.AddSingleton<SqlDependencyEx>(sp => {
            var sd = new SqlDependencyEx("Server=myserver; Database=mydatabase; Trusted_Connection=True;",
                "mydatabase",
                "mytable");
            sd.Start();  
            return sd;
        });

在我的控制器中(因为我使用了React视图,它只是家庭控制器)

public class HomeController : Controller {

    private readonly SqlDependencyEx _tracking;

    public HomeController(SqlDependencyEx tracking, IServiceProvider serviceProvider) {
        _tracking = tracking;
        _tracking.TableChanged += (o, args) => { OnChange(serviceProvider);};                
    }

    private void OnChange(IServiceProvider sp) {
        if(MyHub.ConnectedIds.Count > 0) {
            //get contexts via service providors
            var context = sp.GetService(typeof(DbContext)) as DbContext;
            var hubcontext = sp.GetService(typeof(IHubContext<MyHub>)) as IHubContext<MyHub>;

            //query count and update via singalR
            int countA = context.mytable.Where(x => x.value == 1).Count();
            hubcontext.Clients.All.InvokeAsync("countA", countA);

            int countB = context.mytable
                .Include(t => t.othertable)                    
                .Where(t => t.othertable.value >= 1)
                .Count();
            hubcontext.Clients.All.InvokeAsync("countB", countB);
        }
    }

    public IActionResult Index() {
        return View();
    }
}

1 个答案:

答案 0 :(得分:0)

所以我决定使用一个静态类来获取服务提供者对象并在StartUp.Configure方法中设置它。

在StartUp.cs中,我将Configure方法更改为另一个为我提供服务提供者的重载:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime, IServiceProvider sp)
{
    var props = new dashboard.Models.Tracking.Tracker.Props {
            dbConn = (sp.GetService<DATABASEContext>() as COTSContext).Database.GetDbConnection().ConnectionString,
            dbName = "DATABASE",
            dbTable = "TABLE"
        };

    Models.Tracking.Tracker.Start(props, sp);
}

制作了一个静态类Tracker,其方法为Start(Tracker.Props props, IServiceProvider sp)

跟踪器类:

using System;
using System.Linq;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using ServiceBrokerListener.Domain;
using PROJECT.Models.Queries;

namespace PROJECT.Models.Tracking
{
    public static class Tracker
    {
        public struct Props { public string dbConn, dbName, dbTable; }
        private static SqlDependencyEx dependency;
        public static void Start(Tracker.Props props, IServiceProvider sp)
        {
            if (dependency == null)
            {
                dependency = new SqlDependencyEx(props.dbConn, props.dbName, props.dbTable, identity: 1);
                RegisterEvents(dependency, sp);
                dependency.Start();
            }
        }

        private static void RegisterEvents(SqlDependencyEx dp, IServiceProvider sp)
        {
            dp.TableChanged += (obj, e) =>
            {
                if (MyHub.ConnectedIds.Count > 0)
                {
                    //db and hub context from service provider
                    var context = sp.GetService(typeof(DATABASEContext)) as DATABASEContext;
                    var hubcontext = sp.GetService(typeof(IHubContext<MyHub>)) as IHubContext<MyHub>;

                    //call hub to launch event, db context has extension for count query
                    hubcontext.Clients.All.InvokeAsync("countA", context.GetCountA())
                    hubcontext.Clients.All.InvokeAsync("countB", context.GetCountB())
                }
            };
        }
    }
}