internal static ArticleInfo[] MatchArticles(int[] contentIds, ConditionBase condition, MatchMode mode) { var fields = GetFieldInfo(condition); var count = GetFieldCount(condition); var schema = MatchContents(contentIds, fields); schema = Validate(schema, contentIds, mode, count); if (schema.Any()) { var parameters = new Dictionary <string, object>(); var cnd = condition.Clone().Select <ValueCondition>(c => { string parameterKey; if (parameters.ContainsValue(c.Value)) { parameterKey = parameters.Single(e => e.Value == c.Value).Key; } else { parameterKey = "@p" + parameters.Count; parameters[parameterKey] = c.Value; } return(new ParameterCondition { Parameter = parameterKey }); }); var query = GetQuery(schema, cnd); return(MatchArticles(parameters, query)); } return(new ArticleInfo[0]); }
private static string GetQuery(SchemaInfo[] schema, ConditionBase condition) { var sb = new StringBuilder(); var groups = schema.GroupBy(s => s.RootContentId).ToArray(); var n = 1; foreach (var group in groups) { var contentId = group.Key; var needGrouping = false; var aliaces = group .Where(s => s.RefContentId == null) .Select(s => new { Alias = s.Alias + "." + s.Field, Type = s.DataType, TypeId = s.AttributeTypeId }) .Distinct() .ToArray(); var where = condition .Clone() .Where <FieldCondition>(c => aliaces.Any(a => a.Alias == c.GetCurrentExpression() && a.Type == c.Type)) .Where <ComparitionCondition>(c => c.Conditions.Length > 1) .Where <ComparitionCondition>(c => ComparitionPredicate(c, e => aliaces.First(a => e == a.Alias).TypeId)) .Where <NotCondition>(c => c.Conditions.Length > 0) .Select <LogicalCondition>(c => c.Conditions.Length == 1 ? c.Conditions[0] : c) .Update <FieldCondition>(c => c.CastToString = aliaces.Any(a => a.Alias == c.GetCurrentExpression() && new[] { 9, 10 }.Contains(a.TypeId))) .GetCurrentExpression(); sb.AppendLine("SELECT"); sb.AppendLine("\troot.CONTENT_ITEM_ID [Id],"); sb.AppendFormat("\t{0} [ContentId]", contentId); sb.AppendLine(); sb.AppendLine("FROM"); sb.AppendFormat("\tCONTENT_{0}_UNITED root", contentId); sb.AppendLine(); foreach (var s in group.Where(s => s.RefContentId != null)) { if (s.LinkId != null) { needGrouping = true; sb.AppendFormat(LinkJoinTemplate, s.Alias, s.Field); sb.AppendLine(); sb.AppendFormat(MtMJoinTemplate, s.RefContentId, s.Alias, s.Field); } if (s.BackwardField != null) { needGrouping = s.AttributeTypeId != 2; sb.AppendFormat(MoOJoinTemplate, s.RefContentId, s.Alias, s.Field, s.BackwardField); } else { sb.AppendFormat(OtMJoinTemplate, s.RefContentId, s.Alias, s.Field); } sb.AppendLine(); } sb.AppendLine("WHERE"); sb.Append("\t"); sb.AppendLine(where); if (needGrouping) { sb.AppendLine("GROUP BY"); sb.AppendLine("\troot.CONTENT_ITEM_ID"); } if (n < groups.Length) { sb.AppendLine(); sb.AppendLine("UNION"); sb.AppendLine(); } n++; } return(sb.ToString()); }