/// <summary>
 /// <see cref="ShortMessageAttachment.ShortMessageRef" /> is not initialized when the entity is created. Clients could call this method to load it provided a proper delegate <see cref="ShortMessageAttachment.DelLoadShortMessageRef" /> was setup
 /// before calling it.
 /// </summary>
 public void LoadShortMessageRef()
 {
     if (_ShortMessageRef != null)
         return;
     if (DelLoadShortMessageRef != null)
         _ShortMessageRef = DelLoadShortMessageRef();
 }
 /// <summary>
 /// Internal use
 /// </summary>
 public ShortMessage ShallowCopy(bool allData = false, bool preserveState = false)
 {
     ShortMessage e = new ShortMessage();
     e.StartAutoUpdating = false;
     e.ID = ID;
     e.CreatedDate = CreatedDate;
     e.MsgText = MsgText;
     if (preserveState)
         e.IsMsgTextModified = IsMsgTextModified;
     else
         e.IsMsgTextModified = false;
     e.IsNotReceived = IsNotReceived;
     if (preserveState)
         e.IsIsNotReceivedModified = IsIsNotReceivedModified;
     else
         e.IsIsNotReceivedModified = false;
     e.LastModified = LastModified;
     if (preserveState)
         e.IsLastModifiedModified = IsLastModifiedModified;
     else
         e.IsLastModifiedModified = false;
     e.MsgDataLastModified = MsgDataLastModified;
     if (preserveState)
         e.IsMsgDataLastModifiedModified = IsMsgDataLastModifiedModified;
     else
         e.IsMsgDataLastModifiedModified = false;
     e.MsgDataLink = MsgDataLink;
     if (preserveState)
         e.IsMsgDataLinkModified = IsMsgDataLinkModified;
     else
         e.IsMsgDataLinkModified = false;
     e.MsgDataMime = MsgDataMime;
     if (preserveState)
         e.IsMsgDataMimeModified = IsMsgDataMimeModified;
     else
         e.IsMsgDataMimeModified = false;
     e.MsgTitle = MsgTitle;
     if (preserveState)
         e.IsMsgTitleModified = IsMsgTitleModified;
     else
         e.IsMsgTitleModified = false;
     e.ApplicationID = ApplicationID;
     e.FromID = FromID;
     e.TypeID = TypeID;
     e.GroupID = GroupID;
     e.ReplyToID = ReplyToID;
     e.ToID = ToID;
     if (allData)
     {
         e.MsgData = MsgData;
         if (preserveState)
             e.IsMsgDataModified = IsMsgDataModified;
         else
             e.IsMsgDataModified = false;
     }
     e.DistinctString = GetDistinctString(true);
     e.IsPersisted = IsPersisted;
     if (preserveState)
         e.IsEntityChanged = IsEntityChanged;
     else
         e.IsEntityChanged = false;
     e.StartAutoUpdating = true;
     return e;
 }
 /// <summary>
 /// <see cref="ShortMessage.UpperRef" /> is not initialized when the entity is created. Clients could call this method to load it provided a proper delegate <see cref="ShortMessage.DelLoadUpperRef" /> was setup
 /// before calling it.
 /// </summary>
 public void LoadUpperRef()
 {
     if (ReplyToID == null || _UpperRef != null)
         return;
     if (DelLoadUpperRef != null)
         _UpperRef = DelLoadUpperRef();
 }
 /// <summary>
 /// Merge changes inside entity <paramref name="from" /> to the entity <paramref name="to" />. Any changes in <paramref name="from" /> that is not changed in <paramref name="to" /> is updated inside <paramref name="to" />.
 /// </summary>
 /// <param name="from">The "old" entity acting as merging source.</param>
 /// <param name="to">The "new" entity which inherits changes made in <paramref name="from" />.</param>
 /// <returns>
 /// </returns>
 public static void MergeChanges(ShortMessage from, ShortMessage to)
 {
     if (to.IsPersisted)
     {
         if (from.IsMsgTextModified && !to.IsMsgTextModified)
         {
             to.MsgText = from.MsgText;
             to.IsMsgTextModified = true;
         }
         if (from.IsIsNotReceivedModified && !to.IsIsNotReceivedModified)
         {
             to.IsNotReceived = from.IsNotReceived;
             to.IsIsNotReceivedModified = true;
         }
         if (from.IsLastModifiedModified && !to.IsLastModifiedModified)
         {
             to.LastModified = from.LastModified;
             to.IsLastModifiedModified = true;
         }
         if (from.IsMsgDataModified && !to.IsMsgDataModified)
         {
             to.MsgData = from.MsgData;
             to.IsMsgDataModified = true;
         }
         if (from.IsMsgDataLastModifiedModified && !to.IsMsgDataLastModifiedModified)
         {
             to.MsgDataLastModified = from.MsgDataLastModified;
             to.IsMsgDataLastModifiedModified = true;
         }
         if (from.IsMsgDataLinkModified && !to.IsMsgDataLinkModified)
         {
             to.MsgDataLink = from.MsgDataLink;
             to.IsMsgDataLinkModified = true;
         }
         if (from.IsMsgDataMimeModified && !to.IsMsgDataMimeModified)
         {
             to.MsgDataMime = from.MsgDataMime;
             to.IsMsgDataMimeModified = true;
         }
         if (from.IsMsgTitleModified && !to.IsMsgTitleModified)
         {
             to.MsgTitle = from.MsgTitle;
             to.IsMsgTitleModified = true;
         }
     }
     else
     {
         to.IsPersisted = from.IsPersisted;
         to.ID = from.ID;
         to.CreatedDate = from.CreatedDate;
         to.MsgText = from.MsgText;
         to.IsMsgTextModified = from.IsMsgTextModified;
         to.IsNotReceived = from.IsNotReceived;
         to.IsIsNotReceivedModified = from.IsIsNotReceivedModified;
         to.LastModified = from.LastModified;
         to.IsLastModifiedModified = from.IsLastModifiedModified;
         to.MsgData = from.MsgData;
         to.IsMsgDataModified = from.IsMsgDataModified;
         to.MsgDataLastModified = from.MsgDataLastModified;
         to.IsMsgDataLastModifiedModified = from.IsMsgDataLastModifiedModified;
         to.MsgDataLink = from.MsgDataLink;
         to.IsMsgDataLinkModified = from.IsMsgDataLinkModified;
         to.MsgDataMime = from.MsgDataMime;
         to.IsMsgDataMimeModified = from.IsMsgDataMimeModified;
         to.MsgTitle = from.MsgTitle;
         to.IsMsgTitleModified = from.IsMsgTitleModified;
         to.ApplicationID = from.ApplicationID;
         to.FromID = from.FromID;
         to.TypeID = from.TypeID;
         to.GroupID = from.GroupID;
         to.ReplyToID = from.ReplyToID;
         to.ToID = from.ToID;
     }
 }
 /// <summary>
 /// Update changes to the current entity compared to an input <paramref name="newdata" /> and set the entity to a proper state for updating.
 /// </summary>
 /// <param name="newdata">The "new" entity acting as the source of the changes, if any.</param>
 /// <returns>
 /// </returns>
 public void UpdateChanges(ShortMessage newdata)
 {
     int cnt = 0;
     if (MsgText != newdata.MsgText)
     {
         MsgText = newdata.MsgText;
         IsMsgTextModified = true;
         cnt++;
     }
     if (IsNotReceived != newdata.IsNotReceived)
     {
         IsNotReceived = newdata.IsNotReceived;
         IsIsNotReceivedModified = true;
         cnt++;
     }
     if (LastModified != newdata.LastModified)
     {
         LastModified = newdata.LastModified;
         IsLastModifiedModified = true;
         cnt++;
     }
     bool bMsgData = MsgData == null && newdata.MsgData != null ||
                                                  MsgData != null && newdata.MsgData == null ||
                                                  MsgData != null && newdata.MsgData != null && MsgData.Length != newdata.MsgData.Length;
     if (!bMsgData && MsgData != null)
     {
         for (int i = 0; i < MsgData.Length; i++)
         {
             bMsgData = MsgData[i] != newdata.MsgData[i];
             if (bMsgData)
                 break;
         }
     }
     if (bMsgData)
     {
         MsgData = newdata.MsgData;
         IsMsgDataModified = true;
         cnt++;
     }
     if (MsgDataLastModified != newdata.MsgDataLastModified)
     {
         MsgDataLastModified = newdata.MsgDataLastModified;
         IsMsgDataLastModifiedModified = true;
         cnt++;
     }
     if (MsgDataLink != newdata.MsgDataLink)
     {
         MsgDataLink = newdata.MsgDataLink;
         IsMsgDataLinkModified = true;
         cnt++;
     }
     if (MsgDataMime != newdata.MsgDataMime)
     {
         MsgDataMime = newdata.MsgDataMime;
         IsMsgDataMimeModified = true;
         cnt++;
     }
     if (MsgTitle != newdata.MsgTitle)
     {
         MsgTitle = newdata.MsgTitle;
         IsMsgTitleModified = true;
         cnt++;
     }
     IsEntityChanged = cnt > 0;
 }
 /// <summary>
 /// Whether or not the present entity is identitical to <paramref name="other" />, in the sense that they have the same (set of) primary key(s).
 /// </summary>
 /// <param name="other">The entity to be compared to.</param>
 /// <returns>
 ///   The result of comparison.
 /// </returns>
 public bool IsEntityIdentical(ShortMessage other)
 {
     if (other == null)
         return false;
     if (ID != other.ID)
         return false;
     return true;
 }              
 /// <summary>
 /// Whether or not the present entity is identitical to <paramref name="other" />, in the sense that they have the same (set of) intrinsic identifiers.
 /// </summary>
 /// <param name="other">The entity to be compared to.</param>
 /// <returns>
 ///   The result of comparison.
 /// </returns>
 public bool IsEntityTheSame(ShortMessage other)
 {
     if (other == null)
         return false;
     else
         return ID == other.ID;
 }              
 public static string GetJsonMessage(ShortMessage msg, string userId, UserGroup g, bool dialog, string matchId = null)
 {
     string json = "{ ";
     json += @"""id"": """ + msg.ID + @""", ";
     json += @"""from"": " + GetJsonUser(msg.User_FromID) + @", ";
     json += @"""groupNodes"": [ ";
     string grp = "";
     string path = "";
     foreach (var gn in g.DistinctString.Split('/'))
     {
         if (gn.Trim().Length > 0)
         {
             path += (path == "" ? "" : "/") + gn;
             grp += @"{ ""name"": """ + gn + @""", ""path"": """ + path + @""" }, ";
         }
     }
     if (grp != "")
         json += grp.TrimEnd(" ,".ToCharArray()) + " ";
     json +=  "], ";
     json += @"""groupId"": """ + g.ID + @""", ";
     json += @"""replyToId"": """ + (msg.ReplyToID == null ? "" : msg.ReplyToID) + @""", ";
     json += @"""date"": " + GroupChatContext.getUnixJsonTime(msg.CreatedDate) + @", ";
     json += @"""self"": " + (msg.FromID == userId ? "true" : "false") + @", ";
     json += @"""lead"": """ + GroupChatContext.GetLeadText(msg.MsgText).Replace("\"", "\\\"") + @""", ";
     json += @"""text"": """ + msg.MsgText.Replace("\"", "\\\"") + @""", ";
     json += @"""isMatch"": " + (matchId == msg.ID ? "true" : "false") + ", ";
     json += @"""score"": ";
     if (msg.ChangedShortMessageAudiences != null)
     {
         int cnt = 0;
         foreach (var v in msg.ChangedShortMessageAudiences)
             cnt += v.VoteCount;
         json += cnt;
     }
     else
         json += "0";
     if (dialog)
     {
         json += @", ""replies"": [ ";
         if (msg.ChangedShortMessages != null)
         {
             string subjson = "";
             foreach (var r in from d in msg.ChangedShortMessages orderby d.CreatedDate ascending select d)
                 subjson += GetJsonMessage(r, userId, g, true, matchId) + ", ";
             json += subjson.TrimEnd(" ,".ToCharArray()) + " ";
         }
         json += "]";
     }
     json += " }";
     return json;
 }
 public static string GetJsonMessage(ShortMessage msg, string userId, bool dialog, string matchId = null)
 {
     string json = "{ ";
     json += @"""id"": """ + msg.ID + @""", ";
     json += @"""from"": " + GetJsonUser(msg.User_FromID) + @", ";
     json += @"""to"": " + GetJsonUser(msg.User_ToID) + @", ";
     json += @"""replyToId"": """ + (msg.ReplyToID == null ? "" : msg.ReplyToID) + @""", ";
     json += @"""date"": " + GroupChatContext.getUnixJsonTime(msg.CreatedDate) + @", ";
     json += @"""isOffline"": " + (msg.IsNotReceived.HasValue && msg.IsNotReceived.Value ? "true" : "false") + @", ";
     json += @"""self"": " + (msg.FromID == userId ? "true" : "false") + @", ";
     json += @"""lead"": """ + GroupChatContext.GetLeadText(msg.MsgText).Replace("\"", "\\\"") + @""", ";
     json += @"""text"": """ + msg.MsgText.Replace("\"", "\\\"") + @""", ";
     json += @"""isMatch"": " + (matchId == msg.ID ? "true" : "false") + ", ";
     json += @"""score"": ";
     if (msg.ChangedShortMessageAudiences != null)
     {
         int cnt = 0;
         foreach (var v in msg.ChangedShortMessageAudiences)
             cnt += v.VoteCount;
         json += cnt;
     }
     else
         json += "0";
     if (dialog)
     {
         json += @", ""replies"": [ ";
         if (msg.ChangedShortMessages != null)
         {
             string subjson = "";
             foreach (var r in from d in msg.ChangedShortMessages orderby d.CreatedDate ascending select d)
                 subjson += GetJsonMessage(r, userId, true, matchId) + ", ";
             json += subjson.TrimEnd(" ,".ToCharArray()) + " ";
         }
         json += "]";
     }
     json += " }";
     return json;
 }
 public static string GetJsonMessage(ShortMessage msg, string userId, User peer, bool dialog)
 {
     string json = "{ ";
     json += @"""id"": """ + msg.ID + @""", ";
     json += @"""from"": """ + msg.User_FromID.Username + @""", ";
     json += @"""fromId"": """ + msg.FromID + @""", ";
     json += @"""to"": """ + peer.Username + @""", ";
     json += @"""toId"": """ + peer.ID + @""", ";
     json += @"""replyToId"": """ + (msg.ReplyToID == null ? "" : msg.ReplyToID) + @""", ";
     json += @"""date"": " + GroupChatContext.getUnixJsonTime(msg.CreatedDate) + @", ";
     json += @"""self"": false, ";
     json += @"""text"": """ + msg.MsgText.Replace("\"", "\\\"") + @"""";
     if (dialog)
     {
         json += @", ""replies"": [";
         if (msg.ChangedShortMessages != null)
         {
             string subjson = "";
             foreach (var r in from d in msg.ChangedShortMessages orderby d.CreatedDate ascending select d)
                 subjson += GetJsonMessage(r, userId, peer, true) + ", ";
             json += subjson.TrimEnd(" ,".ToCharArray());
         }
         json += "]";
     }
     json += " }";
     return json;
 }
 public static async Task LeaveUserMessage(string chatHubId, string userId, string peerId, string replyId, string message)
 {
     var cntx = Cntx;
     UserServiceProxy usvc = new UserServiceProxy();
     var u = await usvc.LoadEntityByKeyAsync(cntx, userId);
     var peer = await usvc.LoadEntityByKeyAsync(cntx, peerId);
     ShortMessageServiceProxy msvc = new ShortMessageServiceProxy();
     PeerShotMessage m = new PeerShotMessage();
     var now = DateTime.UtcNow;
     ShortMessage msg = new ShortMessage
     {
         ID = Guid.NewGuid().ToString(),
         ApplicationID = AppId,
         TypeID = 1,
         GroupID = null,
         FromID = userId,
         ToID = peerId,
         ReplyToID = string.IsNullOrEmpty(replyId) ? null : replyId,
         CreatedDate = now,
         LastModified = now,
         MsgText = message,
         IsNotReceived = true
     };
     await msvc.AddOrUpdateEntitiesAsync(cntx, new ShortMessageSet(), new ShortMessage[] { msg });
     UserAssociationServiceProxy uasvc = new UserAssociationServiceProxy();
     DateTime dt = DateTime.UtcNow;
     List<UserAssociation> lass = new List<UserAssociation>();
     UserAssociation utop = await uasvc.LoadEntityByKeyAsync(cntx, userId, peerId, ApplicationContext.ChatAssocTypeId);
     if (utop == null)
     {
         utop = new UserAssociation
         {
             TypeID = ApplicationContext.ChatAssocTypeId,
             FromUserID = userId,
             ToUserID = peerId,
             CreateDate = dt,
             AssocCount = 0,
             LastAssoc = dt,
             InteractCount = 1,
             Votes = 0
         };
     }
     else
         utop.InteractCount++;
     lass.Add(utop);
     if (!string.IsNullOrEmpty(replyId))
     {
         UserAssociation ptou = await uasvc.LoadEntityByKeyAsync(cntx, peerId, userId, ApplicationContext.ChatAssocTypeId);
         if (ptou == null)
         {
             ptou = new UserAssociation
             {
                 TypeID = ApplicationContext.ChatAssocTypeId,
                 FromUserID = peerId,
                 ToUserID = userId,
                 CreateDate = dt,
                 AssocCount = 0,
                 LastAssoc = dt,
                 InteractCount = 0,
                 Votes = 0
             };
         }
         else
             ptou.InteractCount++;
         lass.Add(ptou);
     }
     await uasvc.AddOrUpdateEntitiesAsync(cntx, new UserAssociationSet(), lass.ToArray());
 }
 public static async Task<PeerShotMessage> AddUserMessage(string chatHubId, string userId, string peerId, string replyId, string message, bool record)
 {
     var cntx = Cntx;
     UserServiceProxy usvc = new UserServiceProxy();
     var u = await usvc.LoadEntityByKeyAsync(cntx, userId);
     var peer = await usvc.LoadEntityByKeyAsync(cntx, peerId);
     ShortMessageServiceProxy msvc = new ShortMessageServiceProxy();
     PeerShotMessage m = new PeerShotMessage();
     var now = DateTime.UtcNow;
     ShortMessage msg = new ShortMessage
     {
         ID = Guid.NewGuid().ToString(),
         ApplicationID = AppId,
         TypeID = 1,
         GroupID = null,
         FromID = userId,
         ToID = peerId,
         ReplyToID = string.IsNullOrEmpty(replyId) ? null : replyId,
         CreatedDate = now,
         LastModified = now,
         MsgText = message
     };
     if (record)
     {
         var r = await msvc.AddOrUpdateEntitiesAsync(cntx, new ShortMessageSet(), new ShortMessage[] { msg });
         var _msg = r.ChangedEntities[0].UpdatedItem;
         _msg.User_FromID = u;
         m.msg = GetJsonMessage(_msg, userId, peer, false);
     }
     else
     {
         msg.User_FromID = u;
         m.msg = GetJsonMessage(msg, userId, peer, false);
     }
     UserAssociationServiceProxy uasvc = new UserAssociationServiceProxy();
     var utop = await uasvc.LoadEntityByKeyAsync(cntx, userId, peerId, ApplicationContext.ChatAssocTypeId);
     if (utop != null)
     {
         utop.InteractCount = utop.InteractCount == null ? 1 : utop.InteractCount + 1;
         utop.LastInteract = DateTime.UtcNow;
         await uasvc.AddOrUpdateEntitiesAsync(cntx, new UserAssociationSet(), new UserAssociation[] { utop });
     }
     MembershipPlusServiceProxy svc = new MembershipPlusServiceProxy();
     DateTime dt = DateTime.UtcNow.AddMinutes(-ApplicationContext.OnlineUserInactiveTime);
     MemberCallbackServiceProxy mcbsvc = new MemberCallbackServiceProxy();
     var qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "UserID" },
         new QToken { TkName = "asc" }
     });
     qexpr.FilterTks = new List<QToken>(new QToken[] { 
         new QToken { TkName = "HubID == \"" + chatHubId + "\" && ChannelID == \"" + userId + "\" && ConnectionID is not null && IsDisconnected == false" },
         new QToken { TkName = "&&" },
         new QToken { TkName = "ApplicationID == \"" + AppId + "\" && UserID == \"" + peerId + "\"" },
         new QToken { TkName = "&&" },
         new QToken { TkName = "UserAppMemberRef.LastActivityDate > " + svc.FormatRepoDateTime(dt) }
     });
     MemberCallbackServiceProxy cbsv = new MemberCallbackServiceProxy();
     m.peer = (await cbsv.QueryDatabaseAsync(cntx, new MemberCallbackSet(), qexpr)).SingleOrDefault();          
     return m;
 }
 public static string GetJsonMessage(ShortMessage msg, string userId, UserGroup g, bool dialog)
 {
     string json = "{ ";
     json += @"""id"": """ + msg.ID + @""", ";
     json += @"""from"": """ + msg.User_FromID.Username + @""", ";
     json += @"""fromId"": """ + msg.FromID + @""", ";
     json += @"""group"": """ + g.DistinctString + @""", ";
     json += @"""groupId"": """ + g.ID + @""", ";
     json += @"""replyToId"": """ + (msg.ReplyToID == null ? "" : msg.ReplyToID) + @""", ";
     json += @"""date"": " + getUnixJsonTime(msg.CreatedDate) + @", ";
     json += @"""self"": " + (msg.FromID == userId ? "true" : "false") + @", ";
     json += @"""lead"": """ + GetLeadText(msg.MsgText).Replace("\"", "\\\"") + @""", ";
     json += @"""text"": """ + msg.MsgText.Replace("\"", "\\\"") + @""", ";
     json += @"""score"": ";
     if (msg.ChangedShortMessageAudiences != null)
     {
         int cnt = 0;
         foreach (var v in msg.ChangedShortMessageAudiences)
             cnt += v.VoteCount;
         json += cnt;
     }
     else
         json += "0";
     if (dialog)
     {
         json += @", ""replies"": [ ";
         if (msg.ChangedShortMessages != null)
         {
             string subjson = "";
             foreach (var r in from d in msg.ChangedShortMessages orderby d.CreatedDate ascending select d)
                 subjson += GetJsonMessage(r, userId, g, true) + ", ";
             json += subjson.TrimEnd(" ,".ToCharArray());
         }
         json += " ]";
     }
     json += " }";
     return json;
 }
 public static async Task<ShotMessageNotice> AddUserMessage(string noticeHubId, string chatHubId, string userId, string groupId, string replyId, string message)
 {
     var cntx = Cntx;
     UserGroupServiceProxy gsvc = new UserGroupServiceProxy();
     var g = await gsvc.LoadEntityByKeyAsync(cntx, groupId);
     ShortMessageServiceProxy msvc = new ShortMessageServiceProxy();
     var now = DateTime.UtcNow;
     ShortMessage msg = new ShortMessage
     {
         ID = Guid.NewGuid().ToString(),
         ApplicationID = AppId,
         TypeID = ApplicationContext.ChatShortMsgTypeId,
         GroupID = groupId,
         FromID = userId,
         ToID = null,
         ReplyToID = string.IsNullOrEmpty(replyId) ? null : replyId,
         CreatedDate = now,
         LastModified = now,
         MsgTitle = GetLeadText(message),
         MsgText = message
     };
     await msvc.AddOrUpdateEntitiesAsync(cntx, new ShortMessageSet(), new ShortMessage[] { msg });
     UserServiceProxy usvc = new UserServiceProxy();
     var u = await usvc.LoadEntityByKeyAsync(cntx, userId);
     msg.User_FromID = u;
     UserGroupMemberServiceProxy gmsvc = new UserGroupMemberServiceProxy();
     var cond = new UserGroupMemberSetConstraints
     {
         UserGroupIDWrap = new ForeignKeyData<string> { KeyValue = groupId }
     };
     var qexpr = new QueryExpresion();
     qexpr.OrderTks = new List<QToken>(new QToken[] { new QToken { TkName = "UserID" } });
     qexpr.FilterTks = new List<QToken>(new QToken[] {
         new QToken 
         {
             TkName = "SubscribedTo is not null && SubscribedTo == true"
         }
     });
     var gmbs = await gmsvc.ConstraintQueryAsync(cntx, new UserGroupMemberSet(), cond, qexpr);
     List<MemberNotification> notices = new List<MemberNotification>();
     List<MemberCallback> noteCbks = new List<MemberCallback>();
     MemberCallbackServiceProxy mcbsvc = new MemberCallbackServiceProxy();
     string noticeMsg = "Group message by " + u.Username + " in " + g.DistinctString;
     MemberNotificationTypeServiceProxy ntsvc = new MemberNotificationTypeServiceProxy();
     var ntype = await ntsvc.LoadEntityByKeyAsync(cntx, ApplicationContext.NewMessageNoticeTypeId);
     foreach (var m in gmbs)
     {
         if (m.ActivityNotification.HasValue && m.ActivityNotification.Value)
         {
             var cb = await mcbsvc.LoadEntityByKeyAsync(cntx, groupId, noticeHubId, AppId, m.UserID);
             if (cb.ConnectionID != null && !cb.IsDisconnected)
             {
                 cb.UserAppMemberRef = await mcbsvc.MaterializeUserAppMemberRefAsync(cntx, cb);
                 noteCbks.Add(cb);
             }
         }
         notices.Add(new MemberNotification
         {
             ID = Guid.NewGuid().ToString(),
             Title = noticeMsg,
             CreatedDate = now,
             PriorityLevel = 0,
             ReadCount = 0,
             ApplicationID = AppId,
             TypeID = ApplicationContext.NewMessageNoticeTypeId,
             UserID = userId
         });
     }
     var peers = await ListConnectIds(chatHubId, groupId);
     List<ShortMessageAudience> laud = new List<ShortMessageAudience>();
     foreach (var peer in peers)
     {
         if (peer.UserID != userId)
         {
             var a = new ShortMessageAudience
             {
                 MsgID = msg.ID,
                 UserID = peer.UserID,
                 VoteCount = 0
             };
             laud.Add(a);
         }
     }
     if (laud.Count > 0)
     {
         ShortMessageAudienceServiceProxy audsvc = new ShortMessageAudienceServiceProxy();
         await audsvc.AddOrUpdateEntitiesAsync(cntx, new ShortMessageAudienceSet(), laud.ToArray());
     }
     if (notices.Count > 0)
     {
         MemberNotificationServiceProxy nsvc = new MemberNotificationServiceProxy();
         await nsvc.AddOrUpdateEntitiesAsync(cntx, new MemberNotificationSet(), notices.ToArray());
     }
     return new ShotMessageNotice { msg = GetJsonMessage(msg, userId, g, false), brief = noticeMsg, categ = ntype, peers = peers, callbacks = noteCbks };
 }