/// <summary> /// Constructs a DataView from the datatable which contains all sections available, plus the # of forums in the section. /// Sections and forums are sorted on OrderNo ascending, then on Name ascending. /// </summary> /// <param name="excludeEmptySections">If set to true, empty sections are ignored.</param> /// <returns> /// DataView with all the sections available, including statistics, directly bindable to webcontrols /// </returns> public static DataView GetAllSectionsWStatisticsAsDataView(bool excludeEmptySections) { // join with a derived table, which calculates the number of forums per section. This allows us to re-use the // scalar values in multiple places (projection and where clause), without re-calculating the scalar per row. var qf = new QueryFactory(); var q = qf.Create() .Select(SectionFields.SectionID, SectionFields.SectionName, SectionFields.SectionDescription, SectionFields.OrderNo, qf.Field("ForumCountList", "ForumCount").As("AmountForums")) .From(qf.Section.InnerJoin( qf.Create() .Select(ForumFields.ForumID.Count().As("ForumCount"), ForumFields.SectionID) .GroupBy(ForumFields.SectionID) .As("ForumCountList")) .On(ForumFields.SectionID.Source("ForumCountList")==SectionFields.SectionID)) .OrderBy(SectionFields.OrderNo.Ascending(), SectionFields.SectionName.Ascending()); if(excludeEmptySections) { q.AndWhere(qf.Field("ForumCountList", "ForumCount")!=0); } TypedListDAO dao = new TypedListDAO(); var results = dao.FetchAsDataTable(q); return results.DefaultView; }
/// <summary> /// Gets the threads and accompanying statistics info, in the supportqueue specified. Only the threads which are in the forums in the list of /// accessable forums are returned. /// </summary> /// <param name="accessableForums">A list of accessable forums IDs, which the user has permission to access.</param> /// <param name="supportQueueID">The ID of the support queue to retrieve the threads for.</param> /// <returns>a dataView of Active threads</returns> public static DataView GetAllThreadsInSupportQueueAsDataView(List<int> accessableForums, int supportQueueID) { // return null, if the user does not have a valid list of forums to access if(accessableForums == null || accessableForums.Count <= 0) { return null; } var qf = new QueryFactory(); var q = qf.Create(); var projectionFields = new List<object>(ThreadGuiHelper.BuildQueryProjectionForAllThreadsWithStats(qf)); projectionFields.AddRange(new[] { ForumFields.ForumName, UserFields.NickName.Source("PlacedInQueueUser").As("NickNamePlacedInQueue"), SupportQueueThreadFields.PlacedInQueueByUserID, SupportQueueThreadFields.PlacedInQueueOn, UserFields.NickName.Source("ClaimedThreadUser").As("NickNameClaimedThread"), SupportQueueThreadFields.ClaimedByUserID, SupportQueueThreadFields.ClaimedOn}); q.Select(projectionFields.ToArray()); q.From(ThreadGuiHelper.BuildFromClauseForAllThreadsWithStats(qf) .InnerJoin(qf.Forum).On(ThreadFields.ForumID == ForumFields.ForumID) .InnerJoin(qf.SupportQueueThread).On(ThreadFields.ThreadID == SupportQueueThreadFields.ThreadID) .InnerJoin(qf.User.As("PlacedInQueueUser")) .On(SupportQueueThreadFields.PlacedInQueueByUserID == UserFields.UserID.Source("PlacedInQueueUser")) .LeftJoin(qf.User.As("ClaimedThreadUser")) .On(SupportQueueThreadFields.ClaimedByUserID == UserFields.UserID.Source("ClaimedThreadUser"))); q.Where((ThreadFields.ForumID == accessableForums).And(SupportQueueThreadFields.QueueID == supportQueueID)); q.OrderBy(ThreadFields.ThreadLastPostingDate.Ascending()); TypedListDAO dao = new TypedListDAO(); var threadsInQueue = dao.FetchAsDataTable(q); return threadsInQueue.DefaultView; }
/// <summary> /// Checks the if thread is already bookmarked. /// </summary> /// <param name="userID">User ID.</param> /// <param name="threadID">Thread ID.</param> /// <returns>true if the thread is bookmarked</returns> public static bool CheckIfThreadIsAlreadyBookmarked(int userID, int threadID) { var qf = new QueryFactory(); var q = qf.Create() .Select(BookmarkFields.ThreadID) .Where((BookmarkFields.ThreadID == threadID).And(BookmarkFields.UserID == userID)); var dao = new TypedListDAO(); return dao.GetScalar<int?>(q, null) != null; }
/// <summary> /// 删除服务节点 /// </summary> /// <param name="deleteInfo">删除信息</param> /// <returns>执行结果</returns> public Result DeleteServerNode(DeleteServerNodeCmdDto deleteInfo) { using (var businessWork = WorkFactory.Create()) { #region 参数判断 if (deleteInfo == null || deleteInfo.ServerNodeIds.IsNullOrEmpty()) { return(Result.FailedResult("没有指定要删除的服务节点")); } #endregion var nowServers = ServerNodeDomainService.GetServerNodeList(QueryFactory.Create <ServerNodeQuery>(c => deleteInfo.ServerNodeIds.Contains(c.Id))); //删除逻辑 ServerNodeDomainService.DeleteServerNode(deleteInfo.ServerNodeIds); var commitResult = businessWork.Commit(); return(commitResult.ExecutedSuccess ? Result.SuccessResult("删除成功") : Result.FailedResult("删除失败")); } }
public void TestProductSaleByDayNSUpdateWhere() { var repository = GetRepository(); var queryCount = QueryFactory.Create <ProductSaleByDayNSEntity>(m => !m.ProductName.Contains("没有") && m.ProductName.Contains("修改")); var count = repository.Count(queryCount); var updateEntity = new ProductSaleByDayNSEntity() { DataSource = "测试来源批量修改", ProductName = "商品修改Where" }; var where = QueryFactory.Create <ProductSaleByDayNSEntity>(m => !m.ProductName.Contains("没有") && m.ProductName.Contains("修改"));//where是更新条件 //注意如果是更新用的是实体类的DBModel_ShuffledTempDate Query中的无效 int updateCount = repository.Update(updateEntity, where); Assert.AreEqual(updateCount, count); Assert.AreNotEqual(updateCount, 0); }
public void TestError() { var repository = GetRepository(); var lst = repository.GetList(); var all = lst.AsQueryable(); IQuery <ProductSaleByDayNSEntity> query; var t = lst[2]; Expression <Func <ProductSaleByDayNSEntity, bool> > where; long allCount, c; where = m => m.SysNo == t.SysNo; query = QueryFactory.Create(where); c = repository.Count(query); allCount = all.Count(where); Assert.AreEqual(allCount, c); Assert.AreNotEqual(allCount, 0); }
/// <summary> /// 保存数据验证 /// </summary> /// <returns></returns> protected override bool SaveValidation() { bool valResult = base.SaveValidation(); if (!valResult) { return(valResult); } if (group.CurrentValue == null || group.CurrentValue.SysNo <= 0) { throw new Exception("请设置操作所属分组"); } IQuery groupQuery = QueryFactory.Create <AuthorityOperationGroupQuery>(c => c.SysNo == group.CurrentValue.SysNo); if (!this.Instance <IAuthorityOperationGroupRepository>().Exist(groupQuery)) { throw new Exception("请设置正确的分组"); } return(true); }
/// <summary> /// Checks if the message with the ID specified is first message in thread with id specified. /// </summary> /// <param name="threadID">The thread ID.</param> /// <param name="messageID">The message ID.</param> /// <returns>true if message is first message in thread, false otherwise</returns> public static bool CheckIfMessageIsFirstInThread(int threadID, int messageID) { // use a scalar query, which obtains the first MessageID in a given thread. We sort on posting date ascending, and simply read // the first messageid. If that's not available or not equal to messageID, the messageID isn't the first post in the thread, otherwise it is. var qf = new QueryFactory(); var q = qf.Create() .Select(MessageFields.MessageID) .Where(MessageFields.ThreadID == threadID) .OrderBy(MessageFields.PostingDate.Ascending()) .Limit(1); var dao = new TypedListDAO(); var firstMessageId = dao.GetScalar <int?>(q, null); if (firstMessageId.HasValue) { return(firstMessageId.Value == messageID); } // not found. return(false); }
/// <summary> /// 修改用户授权 /// </summary> /// <param name="userAuthorizes">用户授权信息</param> /// <returns></returns> public static Result ModifyUserAuthorize(IEnumerable <UserAuthorize> userAuthorizes) { if (userAuthorizes.IsNullOrEmpty()) { return(Result.FailedResult("没有指定任何要修改的用户授权信息")); } #region 角色授权 List <long> userIds = userAuthorizes.Select(c => c.User?.SysNo ?? 0).Distinct().ToList(); IQuery userRoleBindQuery = QueryFactory.Create <UserRoleQuery>(c => userIds.Contains(c.UserSysNo)); userRoleBindQuery.AddQueryFields <UserRoleQuery>(c => c.RoleSysNo); IQuery roleAuthBindQuery = QueryFactory.Create <RoleAuthorizeQuery>(); roleAuthBindQuery.And <RoleAuthorizeQuery>(c => c.Role, CriteriaOperator.In, userRoleBindQuery); roleAuthBindQuery.AddQueryFields <RoleAuthorizeQuery>(c => c.Authority); IQuery authQuery = QueryFactory.Create <AuthorityQuery>(); authQuery.And <AuthorityQuery>(c => c.Code, CriteriaOperator.In, roleAuthBindQuery); authQuery.AddQueryFields <AuthorityQuery>(c => c.Code); IEnumerable <Authority> roleAuthoritys = AuthorityService.GetAuthorityList(authQuery); List <string> roleAuthorityCodes = roleAuthoritys.Select(c => c.Code).ToList(); #endregion List <UserAuthorize> saveUserAuthorizes = new List <UserAuthorize>(); userAuthRepository.Remove(userAuthorizes.ToArray()); //移除授权数据 List <UserAuthorize> disableAuthorizes = userAuthorizes.Where(c => c.Disable && roleAuthorityCodes.Contains(c.Authority?.Code)).ToList(); //角色拥有但是用户显示禁用掉的授权 if (!disableAuthorizes.IsNullOrEmpty()) { saveUserAuthorizes.AddRange(disableAuthorizes); } List <UserAuthorize> enableAuthorizes = userAuthorizes.Where(c => !c.Disable && !roleAuthorityCodes.Contains(c.Authority?.Code)).ToList();//用户单独授权的权限 if (!enableAuthorizes.IsNullOrEmpty()) { saveUserAuthorizes.AddRange(enableAuthorizes); } if (!saveUserAuthorizes.IsNullOrEmpty()) { userAuthRepository.Save(saveUserAuthorizes.ToArray()); } return(Result.SuccessResult("修改成功")); }
/// <summary> /// Gets all attachments which have to be approved as data view, filtered on the two passed in list of forum id's. /// It doesn't return the file contents for each attachment, it just returns the other data of each attachment, as well as some other related data. /// </summary> /// <param name="accessableForums">The accessable forums by the user calling.</param> /// <param name="forumsWithApprovalRight">The forums the calling user has attachment approval rights.</param> /// <param name="forumsWithThreadsFromOthers">The forums the calling user can view normal threads from others.</param> /// <param name="userID">The user ID of the calling user.</param> /// <returns>DataView with the data requested.</returns> public static DataView GetAllAttachmentsToApproveAsDataView(List <int> accessableForums, List <int> forumsWithApprovalRight, List <int> forumsWithThreadsFromOthers, int userID) { if ((accessableForums == null) || (accessableForums.Count <= 0)) { // doesn't have access to any forum, return return(null); } if ((forumsWithApprovalRight == null) || (forumsWithApprovalRight.Count <= 0)) { // doesn't have a forum with attachment approval right return(null); } // we'll use a dynamic list for the data to return. This is similar to GetAttachmentsAsDataView, however now we'll add more data + we'll // filter on more things. The data we'll add is the ForumID of the thread containing the messagee the attachment is attached to, as well as // the userid of the poster of the message the attachment is attached to, and the threadid of the thread the message is in. // We've to filter the list of attachments based on the forums accessable by the calling user, the list of forums the calling user has approval // rights on and by the forums on which the user can see other user's threads. We'll create a predicate expression for this, and will add // for each of these filters a separate predicate to this predicate expression and specify AND, so they all have to be true var qf = new QueryFactory(); var q = qf.Create() .Select(AttachmentFields.AttachmentID, AttachmentFields.MessageID, AttachmentFields.Filename, AttachmentFields.Approved, AttachmentFields.Filesize, AttachmentFields.AddedOn, MessageFields.PostedByUserID, ThreadFields.ForumID, ThreadFields.ThreadID) .From(qf.Attachment .InnerJoin(qf.Message).On(AttachmentFields.MessageID == MessageFields.MessageID) .InnerJoin(qf.Thread).On(MessageFields.ThreadID == ThreadFields.ThreadID)) .Where(CreateAttachmentFilter(accessableForums, forumsWithApprovalRight, forumsWithThreadsFromOthers, userID, false)) .OrderBy(AttachmentFields.AddedOn.Ascending()); var attachments = new TypedListDAO().FetchAsDataTable(q); return(attachments.DefaultView); }
/// <summary> /// Execute Remove /// </summary> /// <param name="query">query model</param> protected virtual async Task ExecuteRemoveAsync(IQuery query) { if (query == null) { query = QueryFactory.Create(); } Type entityType = typeof(ET); var keys = QueryConfig.GetPrimaryKeys(entityType); if (keys.IsNullOrEmpty()) { throw new Exception(string.Format("Type:{0} isn't set primary keys", entityType.FullName)); } var dataList = GetList(query); if (dataList == null || dataList.Count <= 0) { return; } await RemoveAsync(dataList.ToArray()).ConfigureAwait(false); }
/// <summary> /// 添加工作分组 /// </summary> /// <param name="jobGroup">工作分组对象</param> /// <returns>执行结果</returns> static void AddJobGroup(JobGroup jobGroup) { #region 级 string parentGroupId = jobGroup.Parent == null ? "" : jobGroup.Parent.Code; JobGroup parentGroup = null; if (!parentGroupId.IsNullOrEmpty()) { IQuery parentQuery = QueryFactory.Create <JobGroupQuery>(c => c.Code == parentGroupId); parentGroup = jobGroupRepository.Get(parentQuery); if (parentGroup == null) { throw new Exception("请选择正确的上级分组"); } } jobGroup.SetParentGroup(parentGroup); #endregion jobGroup.Save();//保存 }
/// <summary> /// 保存计划表达式 /// </summary> /// <param name="data">要保持的数据</param> protected override async Task <IActivationRecord> ExecuteSaveAsync(ExpressionTrigger data) { if (data == null || data.ExpressionItems.IsNullOrEmpty()) { return(null); } List <TriggerExpressionEntity> expressionEntitys = new List <TriggerExpressionEntity>(); expressionEntitys.AddRange(data.ExpressionItems.Select(c => { var expression = c.MapTo <TriggerExpressionEntity>(); expression.TriggerId = data.Id; return(expression); })); //移除现有数据 IQuery removeQuery = QueryFactory.Create <TriggerExpressionQuery>(c => c.TriggerId == data.Id); Remove(removeQuery); //保存数据 return(await SaveEntityAsync(expressionEntitys.ToArray()).ConfigureAwait(false)); }
public void TestProductSaleByDayNSGetPaging() { var stTime = new DateTime(2019, 1, 15); var endTime = new DateTime(2019, 2, 11); var repository = GetRepository(); var query = QueryFactory.Create <ProductSaleByDayNSEntity>(m => m.ProductName.Contains("测试")); query.And(m => m.StatisticalDate >= stTime); query.And(m => m.StatisticalDate < endTime.Date.AddDays(1)); query.OrderByDescing(m => m.StatisticalDate); query.StarSize = 20; query.Rows = 10; //分库的传入stTime,endTime会自动根据时间查询符合条件的库和表 var paging = repository.GetPaging(query); var count = paging.TotalCount; var lst = paging.ToList();//或者paging.Items Assert.True(count > 10); Assert.True(lst.Count == 10); Assert.True(lst.Any(m => m.StatisticalDate > new DateTime(2019, 2, 1))); }
protected QueryBase CreateQuery() { try { string query; if (SelectedOnly.Checked) { query = Query.SelectedText; } else { query = Query.Text; } var q = QueryFactory.Create(Federation).CreateQuery(query, ExecutionMode.Graywulf, OutputTable.Text); q.Verify(); Message.BackColor = Color.Green; Message.Text = "Query OK."; return(q); } catch (ValidatorException ex) { Message.BackColor = Color.Red; Message.Text = String.Format("Query error: {0}", ex.Message); } catch (NameResolverException ex) { Message.BackColor = Color.Red; Message.Text = String.Format("Query error: {0}", ex.Message); } catch (ParserException ex) { Message.BackColor = Color.Red; Message.Text = String.Format("Query error: {0}", ex.Message); } return(null); }
/// <summary> /// Gets all message ids and related info for displaying of the messages which have at least 1 unapproved attachment. /// </summary> /// <param name="accessableForums">The accessable forums by the user calling.</param> /// <param name="forumsWithApprovalRight">The forums the calling user has attachment approval rights.</param> /// <param name="forumsWithThreadsFromOthers">The forums the calling user can view normal threads from others.</param> /// <param name="userId">The user ID of the calling user.</param> /// <returns>List with objects with the data requested.</returns> public static async Task <List <AggregatedUnapprovedAttachmentRow> > GetAllMessagesIDsWithUnapprovedAttachments(List <int> accessableForums, List <int> forumsWithApprovalRight, List <int> forumsWithThreadsFromOthers, int userId) { if ((accessableForums == null) || (accessableForums.Count <= 0)) { // doesn't have access to any forum, return return(null); } if ((forumsWithApprovalRight == null) || (forumsWithApprovalRight.Count <= 0)) { // doesn't have a forum with attachment approval right return(null); } var qf = new QueryFactory(); // We've to filter the list of attachments based on the forums accessable by the calling user, the list of forums the calling user has approval // rights on and by the forums on which the user can see other user's threads. We'll create a predicate expression for this, and will add // for each of these filters a separate predicate to this predicate expression and specify AND, so they all have to be true var q = qf.Create() .Select <AggregatedUnapprovedAttachmentRow>(ThreadFields.Subject, ForumFields.ForumName, MessageFields.MessageID, AttachmentFields.AddedOn) .From(qf.Attachment .InnerJoin(qf.Message).On(AttachmentFields.MessageID.Equal(MessageFields.MessageID)) .InnerJoin(qf.Thread).On(MessageFields.ThreadID.Equal(ThreadFields.ThreadID)) .InnerJoin(qf.Forum).On(ThreadFields.ForumID.Equal(ForumFields.ForumID))) .Where(MessageGuiHelper.CreateAttachmentFilter(accessableForums, forumsWithApprovalRight, forumsWithThreadsFromOthers, userId)) .OrderBy(ForumFields.ForumName.Ascending(), AttachmentFields.AddedOn.Ascending()) .Distinct(); using (var adapter = new DataAccessAdapter()) { return(await adapter.FetchQueryAsync(q).ConfigureAwait(false)); } }
public void TestProductSaleByDayUpdateWhere() { var repository = GetRepository(); var queryCount = QueryFactory.Create <ProductSaleByDayEntity>(m => !m.ProductName.Contains("没有") && m.ProductName.Contains("修改")); queryCount.DBModel.DBModel_ShuffledTempDate = new DateTime(2019, 01, 05); var count = repository.Count(queryCount); var updateEntity = new ProductSaleByDayEntity() { DataSource = "测试来源批量修改", ShopName = "店铺修改Where", DBModel_ShuffledTempDate = new DateTime(2019, 01, 05),//如果用这句话来确定是那个库及表 // StatisticalDate = statisticalDate,//如果要更新StatisticalDate则可以用这句话替代上面那句话 }; var where = QueryFactory.Create <ProductSaleByDayEntity>(m => !m.ProductName.Contains("没有") && m.ProductName.Contains("修改"));//where是更新条件 //注意如果是更新用的是实体类的DBModel_ShuffledTempDate Query中的无效 int updateCount = repository.Update(updateEntity, where); Assert.AreEqual(updateCount, count); Assert.AreNotEqual(updateCount, 0); }
private IQuery <T> QueryiSearch(string propertyName, string queryVal) { string tempQueryFiled = string.Empty; while (tempQueryFiled != queryVal) { tempQueryFiled = queryVal; queryVal = queryVal.Replace("+ ", "+").Replace(" +", "+"); } var query_Search = QueryFactory.Create <T>(); string[] lst = queryVal.Split(new string[] { " ", " ", " ", " "}, StringSplitOptions.RemoveEmptyEntries); foreach (var f in lst) { if (string.IsNullOrWhiteSpace(f)) { continue; } var q = QueryFactory.Create <T>(); string[] lstInfo; if (f.Contains("+") || f.Contains("+")) { lstInfo = f.Split(new string[] { "+", "+" }, StringSplitOptions.RemoveEmptyEntries); } else { lstInfo = new string[] { f }; } foreach (var info in lstInfo) { if (!string.IsNullOrWhiteSpace(info)) { q.And(DBTool.GetContains <T>(propertyName, info)); } } query_Search.Or(q); } return(And(query_Search)); }
/// <summary> /// Gets the system action rights for user. /// </summary> /// <param name="userID">The user ID.</param> /// <param name="actionRights">The action rights to be returned.</param> /// <returns>filled collection</returns> public static async Task <EntityCollection <ActionRightEntity> > GetSystemActionRightsForUserAsync(int userID) { var qf = new QueryFactory(); // the subquery in the filter requires joins as the filter's subquery has to filter on fields in related entities: // WHERE ActionRightID IN (SELECT ActionRightID FROM RoleSystemActionRight INNER JOIN Role ... INNER JOIN RoleUser ... WHERE RoleUser.UserID=userID) var q = qf.ActionRight .Where(ActionRightFields.ActionRightID.In( qf.Create() .Select(RoleSystemActionRightFields.ActionRightID) .From(qf.RoleSystemActionRight.InnerJoin(qf.Role).On(RoleSystemActionRightFields.RoleID.Equal(RoleFields.RoleID)) .InnerJoin(qf.RoleUser).On(RoleFields.RoleID.Equal(RoleUserFields.RoleID))) .Where(RoleUserFields.UserID.Equal(userID))) .And(ActionRightFields.AppliesToSystem.Equal(true))); using (var adapter = new DataAccessAdapter()) { var toReturn = await adapter.FetchQueryAsync(q, new EntityCollection <ActionRightEntity>()).ConfigureAwait(false); return(toReturn); } }
/// <summary> /// edit data /// </summary> /// <param name="obj">object</param> /// <param name="query">query object</param> /// <returns>ICommand object</returns> public virtual ICommand Modify(T obj, IQuery query) { Dictionary <string, dynamic> modifyValues = obj.GetModifyValues(); if (modifyValues == null || modifyValues.Count <= 0) { return(null); } #region 版本控制 string versionFieldName = QueryConfig.GetVersionField(typeof(T)); if (!string.IsNullOrWhiteSpace(versionFieldName)) { if (!modifyValues.ContainsKey(versionFieldName)) { modifyValues.Add(versionFieldName, obj.PropertyValues[versionFieldName] + 1); } query = query ?? QueryFactory.Create(); query.And(versionFieldName, CriteriaOperator.Equal, obj.PropertyValues[versionFieldName]); } #endregion #region 更新时间 string refreshFieldName = QueryConfig.GetRefreshDateField(typeof(T)); if (!string.IsNullOrWhiteSpace(refreshFieldName)) { if (!modifyValues.ContainsKey(refreshFieldName)) { modifyValues.Add(refreshFieldName, DateTime.Now); } } #endregion return(Update(modifyValues.Keys, modifyValues, query)); }
/// <summary> /// 根据查询条件生成查询对象 /// </summary> /// <param name="filter">查询条件</param> /// <returns></returns> IQuery CreateQueryObject(JobGroupFilterDto filter) { if (filter == null) { return(null); } IQuery query = QueryFactory.Create(); if (!filter.Codes.IsNullOrEmpty()) { query.In <JobGroupQuery>(c => c.Code, filter.Codes); } if (!filter.Name.IsNullOrEmpty()) { query.Equal <JobGroupQuery>(c => c.Name, filter.Name); } if (filter.Sort.HasValue) { query.Equal <JobGroupQuery>(c => c.Sort, filter.Sort.Value); } if (!filter.Parent.IsNullOrEmpty()) { query.Equal <JobGroupQuery>(c => c.Parent, filter.Parent); } if (!filter.Root.IsNullOrEmpty()) { query.Equal <JobGroupQuery>(c => c.Root, filter.Root); } if (filter.Level.HasValue) { query.Equal <JobGroupQuery>(c => c.Level, filter.Level.Value); } if (!filter.Remark.IsNullOrEmpty()) { query.Equal <JobGroupQuery>(c => c.Remark, filter.Remark); } return(query); }
/// <summary> /// Gets the threads and accompanying statistics info, in the supportqueues specified. Only the threads which are in the forums in the list of /// accessable forums are returned. /// </summary> /// <param name="accessableForums">A list of accessable forums IDs, which the user has permission to access.</param> /// <param name="supportQueueIds">The support queue IDs to obtain the threads info for.</param> /// <returns> /// a list of aggregated support queue contents rows, one per thread, or an empty list if no forums were accessible. /// </returns> public static async Task <List <AggregatedSupportQueueContentsRow> > GetAllThreadsInSpecifiedSupportQueuesAsync(List <int> accessableForums, int[] supportQueueIds) { // return null, if the user does not have a valid list of forums to access if (accessableForums == null || accessableForums.Count <= 0) { return(new List <AggregatedSupportQueueContentsRow>()); } var qf = new QueryFactory(); var projectionFields = new List <object>(ThreadGuiHelper.BuildQueryProjectionForAllThreadsWithStatsWithForumName(qf)); projectionFields.AddRange(new[] { SupportQueueThreadFields.QueueID, UserFields.NickName.Source("PlacedInQueueUser").As("PlacedInQueueByNickName"), SupportQueueThreadFields.PlacedInQueueByUserID, SupportQueueThreadFields.PlacedInQueueOn, UserFields.NickName.Source("ClaimedThreadUser").As("ClaimedByNickName"), SupportQueueThreadFields.ClaimedByUserID, SupportQueueThreadFields.ClaimedOn }); var q = qf.Create() .Select <AggregatedSupportQueueContentsRow>(projectionFields.ToArray()) .From(ThreadGuiHelper.BuildFromClauseForAllThreadsWithStats(qf) .InnerJoin(qf.Forum).On(ThreadFields.ForumID.Equal(ForumFields.ForumID)) .InnerJoin(qf.SupportQueueThread).On(ThreadFields.ThreadID.Equal(SupportQueueThreadFields.ThreadID)) .InnerJoin(qf.User.As("PlacedInQueueUser")) .On(SupportQueueThreadFields.PlacedInQueueByUserID.Equal(UserFields.UserID.Source("PlacedInQueueUser"))) .LeftJoin(qf.User.As("ClaimedThreadUser")) .On(SupportQueueThreadFields.ClaimedByUserID.Equal(UserFields.UserID.Source("ClaimedThreadUser")))) .Where(ThreadFields.ForumID.In(accessableForums.ToArray()).And(SupportQueueThreadFields.QueueID.In(supportQueueIds))) .OrderBy(SupportQueueThreadFields.QueueID.Ascending(), MessageFields.PostingDate.Source("LastMessage").Ascending()); using (var adapter = new DataAccessAdapter()) { return(await adapter.FetchQueryAsync(q).ConfigureAwait(false)); } }
/// <summary> /// 更新授权操作组 /// </summary> /// <param name="newAuthorityOperationGroup">授权操作组对象</param> /// <returns>执行结果</returns> Result <AuthorityOperationGroup> UpdateAuthorityOperationGroup(AuthorityOperationGroup newAuthorityOperationGroup) { AuthorityOperationGroup authorityOperationGroup = GetAuthorityOperationGroup(newAuthorityOperationGroup.SysNo); if (authorityOperationGroup == null) { return(Result <AuthorityOperationGroup> .FailedResult("没有指定要操作的分组信息")); } //上级 long newParentGroupId = newAuthorityOperationGroup.Parent == null ? 0 : newAuthorityOperationGroup.Parent.SysNo; long oldParentGroupId = authorityOperationGroup.Parent == null ? 0 : authorityOperationGroup.Parent.SysNo; //上级改变后 if (newParentGroupId != oldParentGroupId) { AuthorityOperationGroup parentGroup = null; if (newParentGroupId > 0) { IQuery parentQuery = QueryFactory.Create <AuthorityOperationGroupQuery>(c => c.SysNo == newParentGroupId); parentGroup = authorityOperationGroupRepository.Get(parentQuery); if (parentGroup == null) { return(Result <AuthorityOperationGroup> .FailedResult("请选择正确的上级分组")); } } authorityOperationGroup.SetParentGroup(parentGroup); } //修改信息 authorityOperationGroup.Name = newAuthorityOperationGroup.Name; authorityOperationGroup.Status = newAuthorityOperationGroup.Status; authorityOperationGroup.Remark = newAuthorityOperationGroup.Remark; authorityOperationGroup.Save();//保存 var result = Result <AuthorityOperationGroup> .SuccessResult("修改成功"); result.Data = authorityOperationGroup; return(result); }
/// <summary> /// Finds the users matching the filter criteria. /// </summary> /// <param name="filterOnRole"><see langword="true"/> if [filter on role]; otherwise, <see langword="false"/>.</param> /// <param name="roleID">Role ID.</param> /// <param name="filterOnNickName"><see langword="true"/> if [filter on nick name]; otherwise, <see langword="false"/>.</param> /// <param name="nickName">Name of the nick.</param> /// <param name="filterOnEmailAddress"><see langword="true"/> if [filter on email address]; otherwise, <see langword="false"/>.</param> /// <param name="emailAddress">Email address.</param> /// <returns>User objects matching the query</returns> public static UserCollection FindUsers(bool filterOnRole, int roleID, bool filterOnNickName, string nickName, bool filterOnEmailAddress, string emailAddress) { var qf = new QueryFactory(); var q = qf.User .OrderBy(UserFields.NickName.Ascending()); if (filterOnRole) { q.AndWhere(UserFields.UserID.In(qf.Create().Select(RoleUserFields.UserID).Where(RoleUserFields.RoleID == roleID))); } if (filterOnNickName) { q.AndWhere(UserFields.NickName.Like("%" + nickName + "%")); } if (filterOnEmailAddress) { q.AndWhere(UserFields.EmailAddress.Like("%" + emailAddress + "%")); } UserCollection toReturn = new UserCollection(); toReturn.GetMulti(q); return(toReturn); }
/// <summary> /// 保存 /// </summary> /// <param name="data">要保存的数据</param> protected override async Task <IActivationRecord> ExecuteSaveAsync(TriggerCondition data) { var expressionCondition = data as TriggerExpressionCondition; if (expressionCondition == null || expressionCondition.ExpressionItems.IsNullOrEmpty()) { return(null); } List <TriggerExpressionConditionEntity> expressionConditionEntityList = new List <TriggerExpressionConditionEntity>(); expressionConditionEntityList.AddRange(expressionCondition.ExpressionItems.Select(c => { var entity = c.MapTo <TriggerExpressionConditionEntity>(); entity.TriggerId = data.TriggerId; return(entity); }).ToList()); //移除当前的条件 IQuery removeQuery = QueryFactory.Create <TriggerExpressionConditionQuery>(c => c.TriggerId == data.TriggerId); Remove(removeQuery); //添加新的条件 return(await SaveEntityAsync(expressionConditionEntityList.ToArray()).ConfigureAwait(false)); }
public ActionResult <Paging <ProductSaleByDayNSEntity> > GetJoinPaging() { var repository = GetRepository(); var query = QueryFactory.Create <ProductSaleByDayNSEntity>(m => DBFunction.Function <DateTime>("ISNULL", m.UpdateDate, DateTime.Now) > new DateTime(2019, 6, 26)); var jq = query.InnerJoin(QueryFactory.Create <ShopEntity>(), m => m.ShopID, m => m.SysNo, (x, y) => new { Sale = x, Shop = y }); jq.And(m => m.Shop.ShopName.Contains("店铺")); jq.OrderByDescing(m => m.Sale.Sales + 1); jq.OrderBy(m => m.Sale.ProductName + m.Sale.OutProductID); jq.StarSize = 10; jq.Rows = 5; var res = jq.Select(m => m.Sale); var paging = repository.GetPaging(res); //也可以下面这样返回dto.第二个参数表示第一个表是否要查询所有列. var res2 = jq.Select(m => new PSDto { ShopName = m.Shop.ShopName }, true); var paging2 = repository.GetPaging(res2); var count = paging.TotalCount; var lst = paging.ToList();//或者paging.Items return(paging); }
private void TestProductSaleByDayUpdate() { var repository = GetRepository(); var queryCount = QueryFactory.Create <ProductSaleByDayEntity>(); queryCount.DBModel.DBModel_ShuffledTempDate = new DateTime(2019, 01, 01); queryCount.And(m => m.DataSource == "测试来源修改"); var preCount = repository.Count(queryCount); var query = QueryFactory.Create <ProductSaleByDayEntity>(); query.And(m => m.DataSource != "测试来源修改"); query.OrderByDescing(m => m.StatisticalDate); query.StarSize = new Random().Next(5); query.Rows = 1; query.DBModel.DBModel_ShuffledTempDate = new DateTime(2019, 01, 01); var model = repository.GetPaging(query).ToList()[0]; model.DataSource = "测试来源修改"; model.ProductName = "测试商品修改"; //根据主键更新其他字段 var r = repository.Update(model); Assert.True(r); var nextCount = repository.Count(queryCount); Assert.AreEqual(preCount + 1, nextCount); var entity = repository.Get(new ProductSaleByDayEntity { DBModel_ShuffledTempDate = model.StatisticalDate, SysNo = model.SysNo }); Assert.NotNull(entity); Assert.AreEqual(model.SysNo, entity.SysNo); Assert.AreEqual(model.DataSource, entity.DataSource); Assert.AreEqual(model.ProductName, entity.ProductName); }
/// <summary> /// Returns a list with aggregated data objects, one per thread, for the requested forum and page /// </summary> /// <param name="forumId">ID of Forum for which the Threadlist is required</param> /// <param name="pageNumber">The page number to fetch, which is used to fetch non-sticky posts</param> /// <param name="pageSize">The number of rows to fetch for the page. </param> /// <param name="canViewNormalThreadsStartedByOthers">If set to true, the user calling the method has the right to view threads started by others. /// Otherwise only the threads started by the user calling the method are returned.</param> /// <param name="userId">The userid of the user calling the method.</param> /// <returns>List with all the thread info, aggregated. Sticky threads are sorted to the top.</returns> public static async Task <List <AggregatedThreadRow> > GetAllThreadsInForumAggregatedDataAsync(int forumId, int pageNumber, int pageSize, bool canViewNormalThreadsStartedByOthers, int userId) { // create a query which always fetches the sticky threads, and besides those the threads which are visible to the user. // then sort the sticky threads at the top and page through the resultset. var qf = new QueryFactory(); var offsetStart = pageSize * (pageNumber - 1); if (offsetStart < 0) { offsetStart = 0; } var q = qf.Create() .From(ThreadGuiHelper.BuildFromClauseForAllThreadsWithStats(qf)) .Where(ThreadFields.ForumID.Equal(forumId)) .OrderBy(ThreadFields.IsSticky.Descending(), MessageFields.PostingDate.Source("LastMessage").Descending()) .Select <AggregatedThreadRow>(ThreadGuiHelper.BuildQueryProjectionForAllThreadsWithStats(qf).ToArray()) .Offset(offsetStart) // skip the pages we don't need. .Limit(pageSize + 1); // fetch 1 row extra, which we can use to determine whether there are more pages left. // if the user can't view threads started by others, filter out threads started by users different from userID. Otherwise just filter on forumid and stickyness. if (!canViewNormalThreadsStartedByOthers) { // caller can't view threads started by others: add a filter so that threads not started by calling user aren't enlisted. // however sticky threads are always returned so the filter contains a check so the limit is only applied on threads which aren't sticky // add a filter for sticky threads, add it with 'OR', so sticky threads are always accepted. The whole expression is and-ed to the already existing // expression q.AndWhere((ThreadFields.StartedByUserID.Equal(userId)).Or(ThreadFields.IsSticky.Equal(true))); } using (var adapter = new DataAccessAdapter()) { var toReturn = await adapter.FetchQueryAsync(q).ConfigureAwait(false); return(toReturn); } }
/// <summary> /// 保存管理用户 /// </summary> /// <param name="userList">用户列表</param> public void SaveUserRoleFromUser(IEnumerable <User> userList) { if (userList.IsNullOrEmpty()) { return; } #region 管理账户角色 List <UserRoleEntity> userRoleList = new List <UserRoleEntity>(); List <AdminUser> adminUserList = userList.Where(c => (c is AdminUser) && c != null).Select(c => (AdminUser)c).ToList(); List <long> userIds = new List <long>(); adminUserList.ForEach(a => { userIds.Add(a.SysNo); if (a.Roles.IsNullOrEmpty()) { return; } userRoleList.AddRange(a.Roles.Select(c => new UserRoleEntity() { UserSysNo = a.SysNo, RoleSysNo = c.SysNo })); }); #endregion //移除当前用户绑定的角色 IQuery removeQuery = QueryFactory.Create <UserRoleQuery>(c => userIds.Contains(c.UserSysNo)); UnitOfWork.RegisterCommand(userRoleDal.Delete(removeQuery)); if (!userRoleList.IsNullOrEmpty()) { UnitOfWork.RegisterCommand(userRoleDal.Add(userRoleList).ToArray()); } }
/// <summary> /// 修改执行计划状态 /// </summary> /// <param name="triggers">计划信息</param> public static void ModifyTriggerState(IEnumerable <Trigger> triggers) { if (triggers.IsNullOrEmpty()) { return; } var triggerIds = triggers.Select(c => c.Id).Distinct(); var nowTriggers = triggerRepository.GetList(QueryFactory.Create <TriggerQuery>(c => triggerIds.Contains(c.Id))); if (nowTriggers.IsNullOrEmpty()) { return; } foreach (var trigger in nowTriggers) { var newTrigger = triggers.FirstOrDefault(c => c.Id == trigger.Id); if (newTrigger == null) { continue; } trigger.Status = newTrigger.Status; trigger.Save(); } }
private static NEMILTEC.Interfaces.Service.Reporting.IReportElement _CreateElement( Domain.ReportElement element, NEMILTEC.Interfaces.Service.Reporting.Report report, IDataContext context) { var newElement = ReportElementFactory.Create(element.ReportElementType.Id); newElement.Name = element.Name; newElement.Description = element.Description; newElement.Title = element.Title; newElement.Report = report; if (!element.TemplateInfo.IsNullOrEmpty()) { var templateInfo = ReportElementTemplateInfoSerializer.Deserialize((ReportElementType)element.ReportElementType.Id, element.TemplateInfo); newElement.TemplateInfo = templateInfo; } //if (element.Expression != null) //{ // newElement.Expression = ExpressionFactory.Create(element.Expression, context); //} if (element.Query != null) { newElement.Query = QueryFactory.Create(element.Query); } if (!element.Parameters.IsNullOrEmpty()) { newElement.Parameters = element.Parameters.Select(p => _CreateElementParameter(p, context)).ToArray(); } return(newElement); }
public string Index() { var importGroupId = Guid.NewGuid(); var random = new Random(); var repositoryFactory = RepositoryFactory.Create <ProductSaleByDayEntity>(); var tempDate = new DateTime(2018, 1, 1); while (tempDate <= DateTime.Now.Date) { if (tempDate.Day == 1) { var query = QueryFactory.Create <ProductSaleByDayEntity>(); query.DBModel.DBModel_ShuffledTempDate = tempDate; repositoryFactory.Delete(query); } foreach (var p in dicProduct) { var temp = new ProductSaleByDayEntity(); temp.SysNo = Guid.NewGuid(); temp.DataSource = lstDataSource[random.Next(lstDataSource.Count)]; temp.ShopID = dicShop.Keys.ToList()[random.Next(dicShop.Count)]; temp.ShopName = dicShop[temp.ShopID]; temp.ProductID = p.Key; temp.OutProductID = p.Value; temp.ProductName = p.Value; temp.Sales = random.Next(100000); temp.StatisticalDate = tempDate; temp.UpdateDate = temp.CreateDate = DateTime.Now; temp.UpdateUserID = temp.CreateUserID = Guid.NewGuid(); temp.ImportGroupId = importGroupId; repositoryFactory.Add(temp); } tempDate = tempDate.AddDays(1); } return("初始化成功"); }
public Task DeleteAsync(T entity) { return(Task.Run(() => { WriteConcernResult result; IMongoQuery query = QueryFactory.Create(entity); try { result = Collection.Remove(query); } catch (MongoWriteConcernException e) { throw HandleWriteException(e); } catch (Exception e) { throw new ApplicationException("Mongo driver failure.", e); } CheckWriteResult(result, true); })); }
/// <summary> /// Gets the last pageSize threads in which the user specified participated with one or more messages for the page specified. /// Threads which aren't visible for the calling user are filtered out. If pageNumber is 0, pageSize is used to limit the list to the pageSize /// </summary> /// <param name="accessableForums">A list of accessable forums IDs, which the user calling the method has permission to access.</param> /// <param name="participantUserID">The participant user ID of the user of which the threads have to be obtained.</param> /// <param name="forumsWithThreadsFromOthers">The forums with threads from others.</param> /// <param name="callingUserID">The calling user ID.</param> /// <param name="pageSize">Size of the page.</param> /// <param name="pageNumber">The page number to fetch.</param> /// <returns>a dataView of the threads requested</returns> public static DataView GetLastThreadsForUserAsDataView(List<int> accessableForums, int participantUserID, List<int> forumsWithThreadsFromOthers, int callingUserID, int pageSize, int pageNumber) { // return null, if the user does not have a valid list of forums to access if(accessableForums == null || accessableForums.Count <= 0) { return null; } int numberOfThreadsToFetch = pageSize; if(numberOfThreadsToFetch <= 0) { numberOfThreadsToFetch = 25; } var qf = new QueryFactory(); var q = qf.Create() .Select(ThreadGuiHelper.BuildQueryProjectionForAllThreadsWithStats(qf)) .From(ThreadGuiHelper.BuildFromClauseForAllThreadsWithStats(qf)) .Where((ThreadFields.ForumID == accessableForums) .And(ThreadFields.ThreadID.In(qf.Create() .Select(MessageFields.ThreadID) .Where(MessageFields.PostedByUserID == participantUserID))) .And(ThreadGuiHelper.CreateThreadFilter(forumsWithThreadsFromOthers, callingUserID))) .OrderBy(ThreadFields.ThreadLastPostingDate.Descending()); if(pageNumber <= 0) { // no paging // get the last numberOfThreadsToFetch, so specify a limit equal to the numberOfThreadsToFetch specified q.Limit(numberOfThreadsToFetch); } else { // use paging q.Page(pageNumber, numberOfThreadsToFetch); } var dao = new TypedListDAO(); var lastThreads = dao.FetchAsDataTable(q); return lastThreads.DefaultView; }
/// <summary> /// Builds form clause for the query specified for a fetch of all threads with statistics. /// </summary> /// <param name="qf">The query factory to use.</param> /// <returns>ready to use join operand</returns> internal static IJoinOperand BuildFromClauseForAllThreadsWithStats(QueryFactory qf) { return qf.Thread .LeftJoin(qf.User.As("ThreadStarterUser")).On(ThreadFields.StartedByUserID == UserFields.UserID.Source("ThreadStarterUser")) .InnerJoin(qf.Message.As("LastMessage")).On((ThreadFields.ThreadID == MessageFields.ThreadID.Source("LastMessage")) .And(MessageFields.MessageID.Source("LastMessage").Equal( qf.Create() .Select(MessageFields.MessageID) .Where(MessageFields.ThreadID == MessageFields.ThreadID.Source("LastMessage")) .Limit(1) .OrderBy(MessageFields.PostingDate.Descending()) .ToScalar() .ForceRowLimit()))) // force the row limit otherwise the scalar won't have the TOP 1, which will force // the engine to remove the orderby / distinct as it otherwise fails. .LeftJoin(qf.User.As("LastPostingUser")) .On(MessageFields.PostedByUserID.Source("LastMessage") == UserFields.UserID.Source("LastPostingUser")); }
/// <summary> /// Gets the row count for the set of threads in which the user specified participated with one or more messages for the page specified. /// Threads which aren't visible for the calling user are filtered out. /// </summary> /// <param name="accessableForums">A list of accessable forums IDs, which the user calling the method has permission to access.</param> /// <param name="participantUserID">The participant user ID of the user of which the threads have to be obtained.</param> /// <param name="forumsWithThreadsFromOthers">The forums with threads from others.</param> /// <param name="callingUserID">The calling user ID.</param> /// <returns>a dataView of the threads requested</returns> public static int GetRowCountLastThreadsForUserAsDataView(List<int> accessableForums, int participantUserID, List<int> forumsWithThreadsFromOthers, int callingUserID) { // return null, if the user does not have a valid list of forums to access if(accessableForums == null || accessableForums.Count <= 0) { return 0; } var qf = new QueryFactory(); var q = qf.Create() .Select(ThreadGuiHelper.BuildQueryProjectionForAllThreadsWithStats(qf)) .From(ThreadGuiHelper.BuildFromClauseForAllThreadsWithStats(qf)) .Where((ThreadFields.ForumID == accessableForums) .And(ThreadFields.ThreadID.In(qf.Create() .Select(MessageFields.ThreadID) .Where(MessageFields.PostedByUserID == participantUserID))) .And(ThreadGuiHelper.CreateThreadFilter(forumsWithThreadsFromOthers, callingUserID))); var dao = new TypedListDAO(); return dao.GetScalar<int>(qf.Create().Select(Functions.CountRow()).From(q), null); }
/// <summary> /// Gets the active threads. /// </summary> /// <param name="accessableForums">A list of accessable forums IDs, which the user has permission to access.</param> /// <param name="hoursThreshold">The hours threshold for the query to fetch the active threads. All threads within this threshold's period of time (in hours) /// are fetched.</param> /// <param name="forumsWithOnlyOwnThreads">The forums for which the calling user can view other users' threads. Can be null</param> /// <param name="userID">The userid of the calling user.</param> /// <returns>a dataView of Active threads</returns> public static DataView GetActiveThreadsAsDataView(List<int> accessableForums, short hoursThreshold, List<int> forumsWithThreadsFromOthers, int userID) { if (accessableForums == null || accessableForums.Count <= 0) { return null; } var qf = new QueryFactory(); var q = qf.Create() .Select(new List<object>(ThreadGuiHelper.BuildQueryProjectionForAllThreadsWithStats(qf)) { ForumFields.ForumName } .ToArray()) .From(ThreadGuiHelper.BuildFromClauseForAllThreadsWithStats(qf) .InnerJoin(qf.Forum).On(ThreadFields.ForumID == ForumFields.ForumID)) .Where((ThreadFields.ForumID == accessableForums) .And(ThreadFields.IsClosed == false) .And(ThreadFields.MarkedAsDone == false) .And(ThreadFields.ThreadLastPostingDate >= DateTime.Now.AddHours((double)0 - hoursThreshold)) .And(ThreadGuiHelper.CreateThreadFilter(forumsWithThreadsFromOthers, userID))) .OrderBy(ThreadFields.ThreadLastPostingDate.Ascending()); var dao = new TypedListDAO(); var activeThreads = dao.FetchAsDataTable(q); return activeThreads.DefaultView; }
/// <summary> /// Finds the users matching the filter criteria. /// </summary> /// <param name="filterOnRole"><see langword="true"/> if [filter on role]; otherwise, <see langword="false"/>.</param> /// <param name="roleID">Role ID.</param> /// <param name="filterOnNickName"><see langword="true"/> if [filter on nick name]; otherwise, <see langword="false"/>.</param> /// <param name="nickName">Name of the nick.</param> /// <param name="filterOnEmailAddress"><see langword="true"/> if [filter on email address]; otherwise, <see langword="false"/>.</param> /// <param name="emailAddress">Email address.</param> /// <returns>User objects matching the query</returns> public static UserCollection FindUsers(bool filterOnRole, int roleID, bool filterOnNickName, string nickName, bool filterOnEmailAddress, string emailAddress) { var qf = new QueryFactory(); var q = qf.User .OrderBy(UserFields.NickName.Ascending()); if(filterOnRole) { q.AndWhere(UserFields.UserID.In(qf.Create().Select(RoleUserFields.UserID).Where(RoleUserFields.RoleID == roleID))); } if(filterOnNickName) { q.AndWhere(UserFields.NickName.Like("%" + nickName + "%")); } if(filterOnEmailAddress) { q.AndWhere(UserFields.EmailAddress.Like("%" + emailAddress + "%")); } UserCollection toReturn = new UserCollection(); toReturn.GetMulti(q); return toReturn; }
/// <summary> /// Gets all the banned users as a dataview. This is returned as a dataview because only the nicknames are required, so a dynamic list is /// used to avoid unnecessary data fetching. /// </summary> /// <returns>dataview with the nicknames of the users which are banned on the useraccount: the IsBanned property is set for these users.</returns> /// <remarks>This list of nicknames is cached in the application object so these users can be logged off by force.</remarks> public static DataView GetAllBannedUserNicknamesAsDataView() { var qf = new QueryFactory(); var q = qf.Create() .Select(UserFields.NickName) .Where(UserFields.IsBanned == true); var dao = new TypedListDAO(); var results = dao.FetchAsDataTable(q); return results.DefaultView; }
/// <summary> /// Gets the active threads with statistics. /// </summary> /// <param name="accessableForums">A list of accessable forums IDs, which the user has permission to access.</param> /// <param name="hoursThreshold">The hours threshold for the query to fetch the active threads. All threads within this threshold's period of time (in hours) /// are fetched.</param> /// <param name="forumsWithOnlyOwnThreads">The forums for which the calling user can view other users' threads. Can be null</param> /// <param name="userID">The userid of the calling user.</param> /// <returns> /// a dataTable of Active threads with statistics /// </returns> public static DataTable GetActiveThreadsStatisticsAsDataTable(List<int> accessableForums, short hoursThreshold, List<int> forumsWithThreadsFromOthers, int userID) { // return null, if the user does not have a valid list of forums to access if (accessableForums == null || accessableForums.Count <= 0) { return null; } var qf = new QueryFactory(); var q = qf.Create() .Select(ThreadFields.ThreadID.CountDistinct().As("AmountThreads"), MessageFields.MessageID.Count().As("AmountPostings"), ThreadFields.ThreadLastPostingDate.Max().As("LastPostingDate")) .From(qf.Thread.InnerJoin(qf.Message).On(ThreadFields.ThreadID==MessageFields.ThreadID)) .Where((ThreadFields.ForumID == accessableForums) .And(ThreadFields.IsClosed == false) .And(ThreadFields.MarkedAsDone == false) .And(ThreadFields.ThreadLastPostingDate >= DateTime.Now.AddHours((double)0 - hoursThreshold)) .And(ThreadGuiHelper.CreateThreadFilter(forumsWithThreadsFromOthers, userID))); var dao = new TypedListDAO(); return dao.FetchAsDataTable(q); //// create dyn. list and pull statistics using that list. //ResultsetFields fields = new ResultsetFields(3); //fields.DefineField(ThreadFields.ThreadID, 0, "AmountThreads", string.Empty, AggregateFunction.CountDistinct); //fields.DefineField(MessageFields.MessageID, 1, "AmountPostings", string.Empty, AggregateFunction.Count); //fields.DefineField(ThreadFields.ThreadLastPostingDate, 2, "LastPostingDate", string.Empty, AggregateFunction.Max); //RelationCollection relations = new RelationCollection(); //relations.Add(ThreadEntity.Relations.MessageEntityUsingThreadID); //PredicateExpression filter = new PredicateExpression(); //// only the forums the user has access to //filter.Add(ThreadFields.ForumID == accessableForums.ToArray()); //// only the threads which are not closed //filter.AddWithAnd(ThreadFields.IsClosed == false); //// only the threads which are active (== not done) //filter.AddWithAnd(ThreadFields.MarkedAsDone == false); //// only threads which have been updated in the last Globals.HoursForActiveThreadsTreshold hours //filter.AddWithAnd(ThreadFields.ThreadLastPostingDate >= DateTime.Now.AddHours((double)0 - hoursThreshold)); //// Also filter on the threads viewable by the passed in userid, which is the caller of the method. If a forum isn't in the list of //// forumsWithThreadsFromOthers, only the sticky threads and the threads started by userid should be counted / taken into account. //IPredicateExpression threadFilter = ThreadGuiHelper.CreateThreadFilter(forumsWithThreadsFromOthers, userID); //filter.AddWithAnd(threadFilter); //TypedListDAO dao = new TypedListDAO(); //DataTable toReturn = new DataTable(); //dao.GetMultiAsDataTable(fields, toReturn, 0, null, filter, relations, true, null, null, 0, 0); //return toReturn; }
/// <summary> /// Gets the last message in thread, and prefetches the user + usertitle entities. /// </summary> /// <param name="threadID">Thread ID.</param> /// <returns>fetched messageentity with the userentity + usertitle entity fetched as well of the user who posted the message.</returns> public static MessageEntity GetLastMessageInThreadWithUserInfo(int threadID) { var qf = new QueryFactory(); var q = qf.Message .Where(MessageFields.MessageID.Equal( qf.Create() .Select(MessageFields.MessageID.Source("LastMessage")) .Where((MessageFields.ThreadID == MessageFields.ThreadID.Source("LastMessage")) .And(MessageFields.ThreadID.Source("LastMessage")==threadID)) .Limit(1) .OrderBy(MessageFields.PostingDate.Source("LastMessage").Descending()) .ToScalar() .ForceRowLimit())) .WithPath(MessageEntity.PrefetchPathPostedByUser.WithSubPath(UserEntity.PrefetchPathUserTitle)); MessageCollection messages = new MessageCollection(); messages.GetMulti(q); if(messages.Count<=0) { // not found return null; } return messages[0]; }
/// <summary> /// Builds the projection for a dynamic query which contains thread and statistics information. /// </summary> /// <param name="qf">The query factory to use.</param> /// <returns>The fields for the projection</returns> /// <remarks>Doesn't add the forum fields</remarks> internal static object[] BuildQueryProjectionForAllThreadsWithStats(QueryFactory qf) { var toReturn = new List<object>() { ThreadFields.ThreadID, ThreadFields.ForumID, ThreadFields.Subject, ThreadFields.StartedByUserID, ThreadFields.ThreadLastPostingDate, ThreadFields.IsSticky, ThreadFields.IsClosed, ThreadFields.MarkedAsDone, ThreadFields.NumberOfViews, UserFields.NickName.Source("ThreadStarterUser"), qf.Create() .Select(MessageFields.MessageID.Count()) .CorrelatedOver(MessageFields.ThreadID == ThreadFields.ThreadID) .ToScalar() .As("AmountMessages"), UserFields.UserID.Source("LastPostingUser").As("LastPostingByUserID"), UserFields.NickName.Source("LastPostingUser").As("NickNameLastPosting"), MessageFields.MessageID.Source("LastMessage").As("LastMessageID") }; return toReturn.ToArray(); }
/// <summary> /// Checks if the message with the ID specified is first message in thread with id specified. /// </summary> /// <param name="threadID">The thread ID.</param> /// <param name="messageID">The message ID.</param> /// <returns>true if message is first message in thread, false otherwise</returns> public static bool CheckIfMessageIsFirstInThread(int threadID, int messageID) { // use a scalar query, which obtains the first MessageID in a given thread. We sort on posting date ascending, and simply read // the first messageid. If that's not available or not equal to messageID, the messageID isn't the first post in the thread, otherwise it is. var qf = new QueryFactory(); var q = qf.Create() .Select(MessageFields.MessageID) .Where(MessageFields.ThreadID == threadID) .OrderBy(MessageFields.PostingDate.Ascending()) .Limit(1); var dao = new TypedListDAO(); var firstMessageId = dao.GetScalar<int?>(q, null); if(firstMessageId.HasValue) { return firstMessageId.Value == messageID; } // not found. return false; }
/// <summary> /// Returns an entity collection with all User entities of users who are not currently in the given Role /// </summary> /// <param name="roleID">Role to use as filter</param> /// <returns>entitycollection with data requested</returns> public static UserCollection GetAllUsersNotInRole(int roleID) { var qf = new QueryFactory(); var q = qf.User .Where(UserFields.UserID.NotIn(qf.Create().Select(RoleUserFields.UserID).Where(RoleUserFields.RoleID == roleID))) .OrderBy(UserFields.NickName.Ascending()); UserCollection users = new UserCollection(); users.GetMulti(q); return users; }
/// <summary> /// Re-parses all messages from start date till now or when amountToIndex is reached. This routine will read messagetext for a message, /// parse it, and update the MessageTextAsXML field with the parse result. /// </summary> /// <param name="amountToParse">Amount to parse.</param> /// <param name="startDate">Start date.</param> /// <param name="reGenerateHTML">If true, the HTML is also re-generated and saved.</param> /// <returns>the amount of messages re-parsed</returns> public static int ReParseMessages(int amountToParse, DateTime startDate, bool reGenerateHTML, ParserData parserData) { // index is blocks of 100 messages. var qf = new QueryFactory(); var q = qf.Create() .Select(MessageFields.MessageID, MessageFields.MessageText) .Where(MessageFields.PostingDate >= new DateTime(startDate.Year, startDate.Month, startDate.Day, 0, 0, 0, 0)); if(amountToParse <= 0) { // If we don't have a specific amount of messages to parse, then parse all messages posted till Now. q.AndWhere(MessageFields.PostingDate <= DateTime.Now); } TypedListDAO dao = new TypedListDAO(); bool parsingFinished = false; int amountProcessed = 0; int pageSize = 100; int pageNo = 1; while(!parsingFinished) { q.Page(pageNo, pageSize); DataTable messagesToParse = dao.FetchAsDataTable(q); parsingFinished = (messagesToParse.Rows.Count <= 0); if(!parsingFinished) { foreach(DataRow row in messagesToParse.Rows) { MessageEntity directUpdater = new MessageEntity(); directUpdater.IsNew = false; string messageXML = string.Empty; string messageHTML = string.Empty; TextParser.ReParseMessage((string)row["MessageText"], reGenerateHTML, parserData, out messageXML, out messageHTML); // use the directupdater entity to create an update query without fetching the entity first. directUpdater.Fields[(int)MessageFieldIndex.MessageID].ForcedCurrentValueWrite((int)row["MessageID"]); directUpdater.MessageTextAsXml = messageXML; if(reGenerateHTML) { directUpdater.MessageTextAsHTML=messageHTML; } directUpdater.Fields.IsDirty=true; // no transactional update. directUpdater.Save(); } amountProcessed += messagesToParse.Rows.Count; pageNo++; if(amountToParse > 0) { parsingFinished = (amountToParse <= amountProcessed); } } } return amountProcessed; }
/// <summary> /// Returns a DataView object that contains a complete list of threads list for /// the requested forum and required date & time interval /// </summary> /// <param name="forumID">ID of Forum for which the Threadlist is required</param> /// <param name="limiter">Limits the Threadlist to between now and; last 48 Hrs, Last Week, Last Month, Last Year</param> /// <param name="minNumberOfThreadsToFetch">The minimum number of threads to fetch if there are less threads available in the limiter interval</param> /// <param name="minNumberOfNonStickyVisibleThreads">The minimum number of non-sticky visible threads to show. If the # of threads is lower than /// this number (due to the limiter value), the minNumberOfThreadsToFetch are fetched</param> /// <param name="canViewNormalThreadsStartedByOthers">If set to true, the user calling the method has the right to view threads started by others. /// Otherwise only the threads started by the user calling the method are returned.</param> /// <param name="userID">The userid of the user calling the method.</param> /// <returns>DataView with all the threads</returns> public static DataView GetAllThreadsInForumAsDataView(int forumID, ThreadListInterval limiter, short minNumberOfThreadsToFetch, short minNumberOfNonStickyVisibleThreads, bool canViewNormalThreadsStartedByOthers, int userID) { DateTime limiterDate; // convert the limiter enum to a datetime which we can use in the filters on the thread data, where we'll use the limiter date // as a filter for the last posting date of a post in a given thread. switch (limiter) { case ThreadListInterval.Last24Hours: limiterDate = DateTime.Today.AddHours(-24); break; case ThreadListInterval.Last48Hours: limiterDate = DateTime.Today.AddHours(-48); break; case ThreadListInterval.LastWeek: limiterDate = DateTime.Today.AddDays(-7); break; case ThreadListInterval.LastMonth: limiterDate = DateTime.Today.AddMonths(-1); break; case ThreadListInterval.LastYear: limiterDate = DateTime.Today.AddYears(-1); break; default: limiterDate = DateTime.Today.AddHours(-48); break; } var qf = new QueryFactory(); var q = qf.Create(); q.Select(ThreadGuiHelper.BuildQueryProjectionForAllThreadsWithStats(qf)); q.From(ThreadGuiHelper.BuildFromClauseForAllThreadsWithStats(qf)); q.Where(((ThreadFields.IsSticky == true).Or(ThreadFields.ThreadLastPostingDate >= limiterDate)).And(ThreadFields.ForumID == forumID)); // if the user can't view threads started by others, filter out threads started by users different from userID if(!canViewNormalThreadsStartedByOthers) { // caller can't view threads started by others: add a filter so that threads not started by calling user aren't enlisted. // however sticky threads are always returned so the filter contains a check so the limit is only applied on threads which aren't sticky // add a filter for sticky threads, add it with 'OR', so sticky threads are always accepted q.AndWhere((ThreadFields.StartedByUserID == userID).Or(ThreadFields.IsSticky == true)); } q.OrderBy(ThreadFields.IsSticky.Descending(), ThreadFields.IsClosed.Ascending(), ThreadFields.ThreadLastPostingDate.Descending()); var dao = new TypedListDAO(); var threads = dao.FetchAsDataTable(q); // count # non-sticky threads. If it's below a given minimum, refetch everything, but now don't fetch on date filtered but at least the // set minimum. Do this ONLY if the user can view other user's threads. If that's NOT the case, don't refetch anything. DataView stickyThreads = new DataView(threads, ThreadFieldIndex.IsSticky.ToString() + "=false", "", DataViewRowState.CurrentRows); if((stickyThreads.Count < minNumberOfNonStickyVisibleThreads) && canViewNormalThreadsStartedByOthers) { // not enough threads available, fetch again, // first fetch the sticky threads. q = qf.Create(); q.Select(ThreadGuiHelper.BuildQueryProjectionForAllThreadsWithStats(qf)); q.From(ThreadGuiHelper.BuildFromClauseForAllThreadsWithStats(qf)); q.Where((ThreadFields.IsSticky == true).And(ThreadFields.ForumID == forumID)); q.OrderBy(ThreadFields.ThreadLastPostingDate.Descending()); threads = dao.FetchAsDataTable(q); // then fetch the rest. Fetch it into the same datatable object to append the rows to the already fetched sticky threads (if any) q = qf.Create(); q.Select(ThreadGuiHelper.BuildQueryProjectionForAllThreadsWithStats(qf)); q.From(ThreadGuiHelper.BuildFromClauseForAllThreadsWithStats(qf)); q.Where((ThreadFields.IsSticky == false).And(ThreadFields.ForumID == forumID)); q.Limit(minNumberOfThreadsToFetch); q.OrderBy(ThreadFields.ThreadLastPostingDate.Descending()); dao.FetchAsDataTable(q, threads); // sort closed threads to the bottom. Do this in-memory as it's a sort operation after projection. Doing it on the server would mean // a sort operation before projection. return new DataView(threads, string.Empty, ThreadFieldIndex.IsClosed.ToString() + " ASC", DataViewRowState.CurrentRows); } else { return threads.DefaultView; } }
/// <summary> /// Gets the total number of threads in support queues. Only the count of threads which are in the forums in the list of /// accessable forums are returned. /// </summary> /// <param name="accessableForums">A list of accessable forums IDs, which the user has permission to access.</param> /// <returns>total number of threads in support queues</returns> public static int GetTotalNumberOfThreadsInSupportQueues(List<int> accessableForums) { // return 0, if the user does not have a valid list of forums to access if(accessableForums == null || accessableForums.Count <= 0) { return 0; } var qf = new QueryFactory(); var q = qf.Create() .Select(SupportQueueThreadFields.ThreadID.Count().As("NumberOfThreadsInQueues")) .From(qf.SupportQueueThread.InnerJoin(qf.Thread).On(SupportQueueThreadFields.ThreadID == ThreadFields.ThreadID)) .Where(ThreadFields.ForumID == accessableForums); var dao = new TypedListDAO(); return dao.GetScalar<int>(q, null); }
/// <summary> /// Retrieves for all available sections all forums with all relevant statistical information. This information is stored per forum in a /// DataView which is stored in the returned Dictionary, with the SectionID where the forum is located in as Key. /// </summary> /// <param name="availableSections">SectionCollection with all available sections</param> /// <param name="accessableForums">List of accessable forums IDs.</param> /// <param name="forumsWithOnlyOwnThreads">The forums for which the calling user can view other users' threads. Can be null</param> /// <param name="userID">The userid of the calling user.</param> /// <returns> /// Dictionary with per key (sectionID) a dataview with forum information of all the forums in that section. /// </returns> /// <remarks>Uses dataviews because a dynamic list is executed to retrieve the information for the forums, which include aggregate info about /// # of posts.</remarks> public static Dictionary<int, DataView> GetAllAvailableForumsDataViews(SectionCollection availableSections, List<int> accessableForums, List<int> forumsWithThreadsFromOthers, int userID) { Dictionary<int, DataView> toReturn = new Dictionary<int, DataView>(); // return an empty list, if the user does not have a valid list of forums to access if (accessableForums == null || accessableForums.Count <= 0) { return toReturn; } // fetch all forums with statistics in a dynamic list, while filtering on the list of accessable forums for this user. // Create the filter separate of the query itself, as it's re-used multiple times. IPredicateExpression threadFilter = ThreadGuiHelper.CreateThreadFilter(forumsWithThreadsFromOthers, userID); var qf = new QueryFactory(); var q = qf.Create() .Select(ForumFields.ForumID, ForumFields.ForumName, ForumFields.ForumDescription, ForumFields.ForumLastPostingDate, // add a scalar query which retrieves the # of threads in the specific forum. // this will result in the query: // ( // SELECT COUNT(ThreadID) FROM Thread // WHERE ForumID = Forum.ForumID AND threadfilter. // ) As AmountThreads qf.Create() .Select(ThreadFields.ThreadID.Count()) .CorrelatedOver(ThreadFields.ForumID == ForumFields.ForumID) .Where(threadFilter) .ToScalar().As("AmountThreads"), // add a scalar query which retrieves the # of messages in the threads of this forum. // this will result in the query: // ( // SELECT COUNT(MessageID) FROM Message // WHERE ThreadID IN // ( // SELECT ThreadID FROM Thread WHERE ForumID = Forum.ForumID AND threadfilter // ) // ) AS AmountMessages qf.Create() .Select(MessageFields.MessageID.Count()) .Where(MessageFields.ThreadID.In( qf.Create() .Select(ThreadFields.ThreadID) .CorrelatedOver(ThreadFields.ForumID == ForumFields.ForumID) .Where(threadFilter))) .ToScalar().As("AmountMessages"), ForumFields.HasRSSFeed, ForumFields.SectionID) .Where(ForumFields.ForumID == accessableForums) .OrderBy(ForumFields.OrderNo.Ascending(), ForumFields.ForumName.Ascending()); var results = new TypedListDAO().FetchAsDataTable(q); // Now per section create a new DataView in memory using in-memory filtering on the DataTable. foreach(SectionEntity section in availableSections) { // Create view for current section and filter out rows we don't want. Do this with in-memory filtering of the dataview, so we don't // have to execute multiple queries. DataView forumsInSection = new DataView(results, "SectionID=" + section.SectionID, string.Empty, DataViewRowState.CurrentRows); // add to sorted list with SectionID as key toReturn.Add(section.SectionID, forumsInSection); } // return the dictionary return toReturn; }
/// <summary> /// Gets the bookmarks with statistics for the user specified. /// </summary> /// <param name="userID">User ID.</param> /// <returns></returns> public static DataView GetBookmarksAsDataView(int userID) { var qf = new QueryFactory(); var q = qf.Create() .Select(new List<object>(ThreadGuiHelper.BuildQueryProjectionForAllThreadsWithStats(qf)) { ForumFields.ForumName, ForumFields.SectionID }.ToArray()) .From(ThreadGuiHelper.BuildFromClauseForAllThreadsWithStats(qf) .InnerJoin(qf.Forum).On(ThreadFields.ForumID==ForumFields.ForumID)) .Where(ThreadFields.ThreadID.In(qf.Create().Select(BookmarkFields.ThreadID).Where(BookmarkFields.UserID==userID))) .OrderBy(ThreadFields.ThreadLastPostingDate.Descending()); var dao = new TypedListDAO(); var bookmarkedThreads = dao.FetchAsDataTable(q); return bookmarkedThreads.DefaultView; }
/// <summary> /// Gets the bookmark statistics for the user with id passed in. /// </summary> /// <param name="userID">User ID.</param> /// <returns></returns> public static DataTable GetBookmarkStatisticsAsDataTable(int userID) { var qf = new QueryFactory(); var q = qf.Create() .Select(BookmarkFields.ThreadID.CountDistinct().As("AmountThreads"), MessageFields.MessageID.Count().As("AmountPostings"), ThreadFields.ThreadLastPostingDate.Max().As("LastPostingDate")) .From(qf.Bookmark .InnerJoin(qf.Thread).On(BookmarkFields.ThreadID == ThreadFields.ThreadID) .InnerJoin(qf.Message).On(ThreadFields.ThreadID == MessageFields.ThreadID)) .Where(BookmarkFields.UserID == userID); var dao = new TypedListDAO(); return dao.FetchAsDataTable(q); }
/// <summary> /// Will return the StartMessageNo for including it in the URL when redirecting to a page with messages in the given /// thread. The page started with StartMessageNo will contain the message with ID messageID. Paging is done using the /// maxAmountMessagesPerPage property in Application. /// </summary> /// <param name="threadID">ID of the thread to which the messages belong</param> /// <param name="messageID"></param> /// <returns></returns> public static int GetStartAtMessageForGivenMessageAndThread(int threadID, int messageID, int maxAmountMessagesPerPage) { var qf = new QueryFactory(); var q = qf.Create() .Select(MessageFields.MessageID) .Where(MessageFields.ThreadID == threadID) .OrderBy(MessageFields.PostingDate.Ascending()) .Distinct(); var dao = new TypedListDAO(); var dynamicList = dao.FetchAsDataTable(q); int startAtMessage = 0; int rowIndex = 0; if (dynamicList.Rows.Count > 0) { // there are messages. Find the row with messageID. There can be only one row with this messageID for (int i = 0; i < dynamicList.Rows.Count; i++) { if (((int)dynamicList.Rows[i]["MessageID"]) == messageID) { // found the row rowIndex = i; break; } } } startAtMessage = (rowIndex / maxAmountMessagesPerPage) * maxAmountMessagesPerPage; // done return startAtMessage; }