跟踪EntityFramework中的更改并使用SignalR将这些更改通知给客户端应用程序

目录

介绍

背景

使用代码


介绍

在创建基于客户端服务器的 WPF 应用程序时,它可以让多个客户端连接到单个 WebApi 服务,我们需要解决的一个主要问题是在多个客户端应用程序之间同步数据。当连接的应用程序更改数据时,我们需要一种机制来使用刷新的数据更新胖客户端应用程序。SignalR 在这些场景中对推送通知非常有用。但它的另一个重要方面是跟踪所做的修改,以便可以将这些更新通知发送到其他连接的应用程序。

背景

在我之前关于 SignalR 的文章中,我已经解释了如何通过使用 SignalR 来使 WPF 应用程序更具交互性和部署友好性。今天是领先一步,我们使用实体框架跟踪数据库更改,并使用 SignalR 将这些更改通知推送到客户端应用程序。

使用代码

实体框架是当前数据访问的行业标准,我使用 EF 6 SignalR 创建了一个示例应用程序,以演示使用 SignalR 跟踪更改和通知。我们首先通过BaseContext(base DbContext) 类识别更改。这是应该由其他数据库/上下文类实现的类。我们重写该SaveChanges方法。使用该ProcessChnages方法识别和跟踪更改。对于跟踪的每个添加或修改,都会创建一个新的审计事件类型的实体,并将其添加到审计事务中。

public void ProcessChanges()
        {
            foreach (var ent in context.ChangeTracker.Entries<IAuditable>()
                .Where(p => p.State == EntityState.Deleted || 
                p.State == EntityState.Modified || p.State == EntityState.Added))
            {
                //Set the update user/time
                SetAuditTimestamps(ent);

                if (ent.State == EntityState.Added)
                {
                    //Save for processing later, when the ID is generated
                    AdditionEntities.Add(ent);
                }
                else
                {
                    //Process now
                    ModifyEvents.Add(CreateAuditEvent(ent));
                }
            }
        }

        public void TrackModifications()
        {
            if (ModifyEvents.Count == 0 && AdditionEntities.Count == 0)
                return;
            this.auditTxn = new AuditTxn()
            {
                Date = DateTime.Now,
                ServerName = Environment.MachineName,
                AuditEvents = new List<AuditEvent>()
            };
            auditTxn.AuditEvents.AddRange(ModifyEvents);
            context.Set<AuditTxn>().Add(auditTxn);
        }

        public void TrackAdditions()
        {
            if (ModifyEvents.Count == 0 && AdditionEntities.Count == 0)
                return;
            auditTxn.AuditEvents.AddRange(AdditionEntities.Select
                                         (ae => CreateAuditEvent(ae, true)));
        }

这些SignalRExtensions类包含将这些审计事件广播到连接的客户端的 SignalR 方法。该类包含一个ExcludeAuditEvents集合,当我们不想发送对某些域类进行修改的通知时,该集合可用于场景。

public static void BroadcastEntityUpdates<T>(this T ctx) where T : IAuditableContext
        {
            var auditTxns = ctx.AuditTxns.Local;            

            var auditTxn = auditTxns.FirstOrDefault();
            if (auditTxn == null)
            {
                return;
            }
            var context = GlobalHost.ConnectionManager.GetHubContext<BroadcastHub>();

            var notification = new EntityNotification()
            {
                AuditTxnId = auditTxn.AuditTxnId,
                Date = auditTxn.Date,
                ServerName = auditTxn.ServerName,
                EntityEvents = auditTxn.AuditEvents.Where
                               (a => !ExcludedAuditEvents.Contains(a.ObjectType)).Select
                               (e => new EntityEvent()
                {
                    AuditEventId = e.AuditEventId,
                    ObjectId = e.ObjectId,
                    ObjectType = e.ObjectType,
                    Payload = ctx.GetPayload(e),
                    EventType = e.EventType == AuditEventTypes.Added ? 
                    UpdateTypes.Added : e.EventType == AuditEventTypes.Deleted ? 
                    UpdateTypes.Deleted : UpdateTypes.Modified,
                }).ToList()
            };
            context.Clients.All.UpdateEntities(notification);
        }

现在客户端应用程序应该按照我之前的文章探索Signal-R让WPF应用程序交互中的说明工作,其中onmessage处理程序可以配置为使用ObjectIdObjectTypeEntityNotification类中传递来重新加载 EF 数据。

https://www.codeproject.com/Tips/5329997/Tracking-Changes-in-EntityFramework-and-Notifying

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值