![](/img/trans.png)
[英]How can you control the order of SQL updates in EF6 DB model using TPT inheritance?
[英]How to allow SignalR to push updates from DB to the browser using EF6
如何允许SignalR
使用EF6
将更新从SQLServer DB
推送到浏览器。
这是我的操作方法:
public ActionResult Index()
{
var currentGates = _ctx.Transactions
.GroupBy(item => item.SubGateId)
.SelectMany(group => group.OrderByDescending(x => x.TransactionDateTime)
.Take(1))
.Include(g => g.Card)
.Include(g => g.Student)
.Include(g => g.Student.Faculty)
.Include(g => g.Student.Department)
.Include(g => g.SubGate)
.ToList();
return View(currentGates);
}
经过大量搜索,我得到的唯一结果是:
ASP.NET MVC 5 SignalR,SqlDependency 和 EntityFramework 6
我已经尝试了建议的方法,但它没有用,除此之外,我还发现了一个非常重要的安全问题,即在隐藏字段中存储敏感数据!
我的问题是:
如何根据事务表上的任何
Insert
更新我的视图?
所以基本上你需要做的是覆盖SaveChanges()
方法和操作 SignalR function:
public class ApplicationDbContext : IdentityDbContext<IdentityUser>
{
public override int SaveChanges()
{
var entities = ChangeTracker.Entries().Where(x => x.Entity is Transactions && x.State == EntityState.Added) ;
IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
foreach (var entity in entities)
{
hubContext.Clients.All.notifyClients(entity);
}
return base.SaveChanges();
}
}
通常我会插入创建事务的服务或保存更改事件,如@Vince Suggested 但是因为您的新要求
问题是:我无法控制将学生事务推送到数据库的 sdk,所以我希望有一些方法可以直接在数据库表上工作。
在您的情况下,您可以使用 SQL 来查看表格
注意:小心使用SqlDependency class - 它存在memory 泄漏问题。
using(var tableDependency = new SqlTableDependency<Transaction>(conString))
{
tableDependency.OnChanged += TableDependency_Changed;
tableDependency.Start();
}
void TableDependency_Changed(object sender, RecordChangedEventArgs<Transaction> e)
{
if (e.ChangeType != ChangeType.None)
{
var changedEntity = e.Entity;
//You'll need to change this logic to send only to the people you want to
IHubContext hubContext = GlobalHost.ConnectionManager.GetHubContext<MyHub>();
hubContext.Clients.All.notifyClients(entity);
}
}
编辑似乎您可能有其他依赖项,例如包含您想要的结果。 因此,您可以做的是从实体中解析 Id,然后使用 EntityFramework 调用 Get。
if (e.ChangeType != ChangeType.None)
{
var changedEntity = e.Entity;
var id = GetPrimaryKey(changedEntity)
_ctx.Transactions.Find(id);
}
编辑其他方法的方法。
如果您的实体有最后更新的字段,您可以在计时器上扫描表的更改。 客户端有一个计时器,它在最后一次检查更改时发送。 服务器获取最后更新时间戳大于传入时间的所有实体
尽管您无权访问 EF,但您可能有权访问 web api 请求。 每当有人调用更新或创建方法时,只需获取已更改实体的 id,将所有已更改实体的 id 弹出到后台服务,该服务将发送 signalr 通知,
现在唯一的问题是获取主键,这可以通过手动将类型映射到它们的 id 属性来完成,或者可以使用 model 中的元数据来完成,但这有点复杂
请注意,您可能可以修改它,以便它在所有表上通用
我了解您有以下数据流:
所有这些都是第 3 方。 您的目标是拥有一个自定义 ASP.Net web 页面,该页面显示读卡器收到的最新记录:
所以问题基本上是,您的 ASP.net 服务需要被通知受监控数据库表中的更改。
快速而肮脏的方法:
CREATE TABLE state( GateId INT NOT NULL, UserName VARCHAR (20) NOT NULL, PRIMARY KEY (GateId));
此表旨在每个门只有 1 条记录。 6 个门 -> 这张表中有 6 条记录。恕我直言,通过数据库的数据流是一个糟糕的设计决策(或限制)。 如果您的“经理”不仅将数据推送到数据库,而且随后通知所有 SignalR 客户端,那就更好了。 这个数据流基本上是@Vince 回答所假设的。
编辑:由于您已经发布了您正在使用的实际设备,我鼓励您仔细检查是否可以直接连接到读卡器。 一旦设备读取了学生卡,就有办法注册某种回调。 这样做的唯一目标是实现这样的严格数据流/架构:
-> connect 6x card readers to your
-> ASP.Net service which at a single point in your code:
-> updates the database
-> updates the Signal R clients
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.