/// <summary> /// Hack the particular query /// </summary> public bool HackQuery(QueryBuilder builder, SqlStatement sqlStatement, SqlStatement whereClause, PropertyInfo property, String queryPrefix, QueryPredicate predicate, object values, IEnumerable <TableMapping> scopedTables) { // Hack mnemonic queries if (typeof(Concept).IsAssignableFrom(property.PropertyType) && predicate.SubPath == "mnemonic") { // Has this already been joined? var declType = TableMapping.Get(this.m_mapper.MapModelType(property.DeclaringType)); var keyProperty = property.PropertyType == typeof(Guid) ? property : property.DeclaringType.GetRuntimeProperty(property.Name + "Key"); var declProp = declType.GetColumn(this.m_mapper.MapModelProperty(property.DeclaringType, declType.OrmType, keyProperty)); if (declProp.ForeignKey == null) { return(false); // No FK link } var tblMap = TableMapping.Get(this.m_mapper.MapModelType(property.PropertyType)); var fkTbl = TableMapping.Get(declProp.ForeignKey.Table); string directFkName = $"{queryPrefix}{fkTbl.TableName}"; // We have to join to the FK table if (!declProp.IsAlwaysJoin) { var fkColumn = fkTbl.GetColumn(declProp.ForeignKey.Column); sqlStatement.Append($" INNER JOIN {fkTbl.TableName} AS {directFkName}_{declProp.Name} ON ({queryPrefix}{declType.TableName}.{declProp.Name} = {directFkName}_{declProp.Name}.{fkColumn.Name})"); directFkName += $"_{declProp.Name}"; } // We aren't yet joined to our table, we need to join to our table though!!!! if (declProp.ForeignKey.Table != tblMap.OrmType) { var fkKeyColumn = fkTbl.Columns.FirstOrDefault(o => o.ForeignKey?.Table == tblMap.OrmType && o.Name == tblMap.PrimaryKey.First().Name) ?? tblMap.Columns.FirstOrDefault(o => o.ForeignKey?.Table == fkTbl.OrmType && o.Name == fkTbl.PrimaryKey.First().Name); if (fkKeyColumn == null) { return(false); // couldn't find the FK link } // Now we want to filter our FK var tblName = $"{queryPrefix}{declProp.Name}_{tblMap.TableName}"; sqlStatement.Append($" INNER JOIN {tblMap.TableName} AS {tblName} ON ({directFkName}.{fkKeyColumn.Name} = {tblName}.{fkKeyColumn.Name})"); // Append the where clause whereClause.And(builder.CreateWhereCondition(property.PropertyType, predicate.SubPath, values, $"{queryPrefix}{declProp.Name}_", new List <TableMapping>() { tblMap })); // Add obslt_utc version? if (typeof(IDbBaseData).IsAssignableFrom(tblMap.OrmType)) { whereClause.And($"{tblName}.{tblMap.GetColumn(nameof(IDbBaseData.ObsoletionTime)).Name} IS NULL"); } } return(true); } else { return(false); } }
/// <summary> /// Query hack for creation time /// </summary> public bool HackQuery(QueryBuilder builder, SqlStatement sqlStatement, SqlStatement whereClause, Type tmodel, PropertyInfo property, string queryPrefix, QueryPredicate predicate, object values, IEnumerable <TableMapping> scopedTables, params KeyValuePair <String, object>[] queryFilter) { if (property.Name == nameof(IBaseEntityData.CreationTime) && typeof(IVersionedEntity).IsAssignableFrom(tmodel)) // filter by first creation time { // Get the version table (which has var ormMap = scopedTables.SelectMany(o => o.Columns); var replacesVersion = ormMap.FirstOrDefault(o => o.SourceProperty.Name == nameof(IDbVersionedData.ReplacesVersionKey)); var joinCol = replacesVersion.Table.Columns.FirstOrDefault(o => o.SourceProperty.Name == nameof(IDbVersionedData.Key)); whereClause.And($"EXISTS (SELECT 1 FROM {replacesVersion.Table.TableName} AS crt{replacesVersion.Table.TableName} WHERE crt{replacesVersion.Table.TableName}.{joinCol.Name} = {queryPrefix}{replacesVersion.Table.TableName}.{joinCol.Name} AND crt{replacesVersion.Table.TableName}.{replacesVersion.Name} IS NULL "); whereClause.And(builder.CreateWhereCondition(tmodel, predicate.Path, values, "crt", scopedTables.ToList())); whereClause.Append(")"); return(true); } return(false); }
public bool HackQuery(QueryBuilder builder, SqlStatement sqlStatement, SqlStatement whereClause, Type tmodel, PropertyInfo property, string queryPrefix, QueryPredicate predicate, object values, IEnumerable <TableMapping> scopedTables) { if (property.Name == "RcptTo" && property.PropertyType.StripGeneric() == typeof(SecurityUser)) { if (predicate.SubPath == "userName") { if (!(values is IList)) { values = new List <Object>() { values } } ; var lValues = values as IList; var secRepo = ApplicationServiceContext.Current.GetService <ISecurityRepositoryService>(); Guid[] vals = lValues.OfType <String>().Select(u => secRepo.GetUser(u)?.Key).OfType <Guid>().ToArray(); whereClause.And($"rcptTo IN ({String.Join(",", vals.Select(o => $"X'{BitConverter.ToString(((Guid)o).ToByteArray()).Replace("-", "")}'").ToArray())})"); return(true); } else { throw new InvalidOperationException("Cannot map this expression"); } } return(false); } }
/// <summary> /// Hack the query /// </summary> public bool HackQuery(QueryBuilder builder, SqlStatement sqlStatement, SqlStatement whereClause, Type tmodel, PropertyInfo property, string queryPrefix, QueryPredicate predicate, object values, IEnumerable <TableMapping> scopedTables, params KeyValuePair <string, object>[] queryFilter) { if (typeof(SecurityUser) == tmodel && property.Name == nameof(SecurityUser.UserEntity)) { var userkey = TableMapping.Get(typeof(DbUserEntity)).GetColumn(nameof(DbUserEntity.SecurityUserKey), false); var personSubSelect = builder.CreateQuery <UserEntity>(queryFilter.Select(p => new KeyValuePair <String, Object>(p.Key.Replace("userEntity.", ""), p.Value)), null, userkey); var userIdKey = TableMapping.Get(typeof(DbSecurityUser)).PrimaryKey.FirstOrDefault(); whereClause.And($"{userIdKey.Name} IN (").Append(personSubSelect).Append(")"); return(true); } return(false); }
/// <summary> /// Get active policies for the specified securable type /// </summary> public IEnumerable <IPolicyInstance> GetPolicies(object securable) { List <AdoSecurityPolicyInstance> result = null; if (result == null) { using (DataContext context = this.m_configuration.Provider.GetReadonlyConnection()) { try { context.Open(); // Security device if (securable is Core.Model.Security.SecurityDevice sd) { var query = context.CreateSqlStatement <DbSecurityDevicePolicy>().SelectFrom(typeof(DbSecurityPolicy), typeof(DbSecurityDevicePolicy)) .AutoJoin <DbSecurityPolicy, DbSecurityDevicePolicy>(); if (securable is DevicePrincipal dp) { query.AutoJoin <DbSecurityDevice, DbSecurityDevice>() .Where(o => o.PublicId == dp.Identity.Name); var retVal = context.Query <CompositeResult <DbSecurityPolicy, DbSecurityDevicePolicy> >(query) .AsEnumerable().Select(o => new AdoSecurityPolicyInstance(o.Object2, o.Object1, securable)).ToList(); var appClaim = dp.Identities.OfType <Server.Core.Security.ApplicationIdentity>().SingleOrDefault()?.FindAll(SanteDBClaimTypes.Sid).SingleOrDefault() ?? dp.FindAll(SanteDBClaimTypes.SanteDBApplicationIdentifierClaim).SingleOrDefault(); // There is an application claim so we want to add the application policies - most restrictive if (appClaim != null) { var claim = Guid.Parse(appClaim.Value); var aquery = context.CreateSqlStatement <DbSecurityApplicationPolicy>().SelectFrom(typeof(DbSecurityPolicy), typeof(DbSecurityApplicationPolicy)) .AutoJoin <DbSecurityPolicy, DbSecurityApplicationPolicy>() .Where(o => o.SourceKey == claim); retVal.AddRange(context.Query <CompositeResult <DbSecurityPolicy, DbSecurityApplicationPolicy> >(aquery).AsEnumerable().Select(o => new AdoSecurityPolicyInstance(o.Object2, o.Object1, securable))); } result = retVal; } else { result = context.Query <CompositeResult <DbSecurityPolicy, DbSecurityDevicePolicy> >(query.Where(o => o.SourceKey == sd.Key)) .AsEnumerable().Select(o => new AdoSecurityPolicyInstance(o.Object2, o.Object1, securable)).ToList(); } } else if (securable is Core.Model.Security.SecurityRole sr) { var query = context.CreateSqlStatement <DbSecurityRolePolicy>().SelectFrom(typeof(DbSecurityPolicy), typeof(DbSecurityRolePolicy)) .AutoJoin <DbSecurityPolicy, DbSecurityRolePolicy>() .Where(o => o.SourceKey == sr.Key); result = context.Query <CompositeResult <DbSecurityPolicy, DbSecurityRolePolicy> >(query) .AsEnumerable().Select(o => new AdoSecurityPolicyInstance(o.Object2, o.Object1, securable)).ToList(); } else if (securable is Core.Model.Security.SecurityApplication sa) { var query = context.CreateSqlStatement <DbSecurityApplicationPolicy>().SelectFrom(typeof(DbSecurityPolicy), typeof(DbSecurityApplicationPolicy)) .AutoJoin <DbSecurityPolicy, DbSecurityApplicationPolicy>(); if (securable is ApplicationPrincipal ap) { query.AutoJoin <DbSecurityApplication, DbSecurityApplication>() .Where(o => o.PublicId == ap.Identity.Name); } else { query.Where(o => o.SourceKey == sa.Key); } result = context.Query <CompositeResult <DbSecurityPolicy, DbSecurityApplicationPolicy> >(query) .AsEnumerable().Select(o => new AdoSecurityPolicyInstance(o.Object2, o.Object1, securable)).ToList(); } else if (securable is IPrincipal || securable is IIdentity) { var identity = (securable as IPrincipal)?.Identity ?? securable as IIdentity; IEnumerable <CompositeResult <DbSecurityPolicy, DbSecurityPolicyActionableInstance> > retVal = null; SqlStatement query = null; if (!(identity is Server.Core.Security.ApplicationIdentity) && !(identity is DeviceIdentity)) // Is this a user based claim? { // Role policies query = context.CreateSqlStatement <DbSecurityRolePolicy>().SelectFrom(typeof(DbSecurityPolicy), typeof(DbSecurityPolicyActionableInstance)) .InnerJoin <DbSecurityRolePolicy, DbSecurityPolicy>(o => o.PolicyKey, o => o.Key) .InnerJoin <DbSecurityRolePolicy, DbSecurityUserRole>(o => o.SourceKey, o => o.RoleKey) .InnerJoin <DbSecurityUserRole, DbSecurityUser>(o => o.UserKey, o => o.Key) .Where <DbSecurityUser>(o => o.UserName.ToLower() == identity.Name.ToLower()); retVal = context.Query <CompositeResult <DbSecurityPolicy, DbSecurityPolicyActionableInstance> >(query).AsEnumerable(); } // Claims principal, then we want device and app SID if (securable is IClaimsPrincipal cp) { var appClaim = cp.Identities.OfType <Server.Core.Security.ApplicationIdentity>().SingleOrDefault()?.FindAll(SanteDBClaimTypes.Sid).SingleOrDefault() ?? cp.FindAll(SanteDBClaimTypes.SanteDBApplicationIdentifierClaim).SingleOrDefault(); var devClaim = cp.Identities.OfType <Server.Core.Security.DeviceIdentity>().SingleOrDefault()?.FindAll(SanteDBClaimTypes.Sid).SingleOrDefault() ?? cp.FindAll(SanteDBClaimTypes.SanteDBDeviceIdentifierClaim).SingleOrDefault(); IEnumerable <CompositeResult <DbSecurityPolicy, DbSecurityPolicyActionableInstance> > appDevClaim = null; // There is an application claim so we want to add the application policies - most restrictive if (appClaim != null) { var claim = Guid.Parse(appClaim.Value); query = context.CreateSqlStatement <DbSecurityApplicationPolicy>().SelectFrom(typeof(DbSecurityPolicy), typeof(DbSecurityPolicyActionableInstance)) .AutoJoin <DbSecurityPolicy, DbSecurityApplicationPolicy>() .Where(o => o.SourceKey == claim); if (retVal != null) { var usrPolKeys = retVal.AsEnumerable().Select(o => o.Object2.PolicyKey).ToArray(); // App grant only overrides those policies which already exist on user query.And <DbSecurityApplicationPolicy>(o => usrPolKeys.Contains(o.PolicyKey)); } var appResults = context.Query <CompositeResult <DbSecurityPolicy, DbSecurityPolicyActionableInstance> >(query); appDevClaim = appDevClaim?.Union(appResults) ?? appResults; } // There is an device claim so we want to add the device policies - most restrictive if (devClaim != null) { var claim = Guid.Parse(devClaim.Value); query = context.CreateSqlStatement <DbSecurityDevicePolicy>().SelectFrom(typeof(DbSecurityPolicy), typeof(DbSecurityPolicyActionableInstance)) .AutoJoin <DbSecurityPolicy, DbSecurityDevicePolicy>() .Where(o => o.SourceKey == claim); if (retVal != null) { var usrPolKeys = retVal.Select(o => o.Object2.PolicyKey).ToArray(); // Dev grant only overrides those policies which already exist on user query.And <DbSecurityDevicePolicy>(o => usrPolKeys.Contains(o.PolicyKey)); } var devResults = context.Query <CompositeResult <DbSecurityPolicy, DbSecurityPolicyActionableInstance> >(query); appDevClaim = appDevClaim?.Union(devResults) ?? devResults; } if (appDevClaim != null) { retVal = retVal?.Union(appDevClaim) ?? appDevClaim; } } result = retVal.AsEnumerable().Select(o => new AdoSecurityPolicyInstance(o.Object2, o.Object1, securable)).ToList(); this.m_traceSource.TraceEvent(EventLevel.Verbose, "Principal {0} effective policy set {1}", identity?.Name, String.Join(",", result.Select(o => $"{o.Policy.Oid} [{o.Rule}]"))); } else if (securable is Core.Model.Acts.Act pAct) { var query = context.CreateSqlStatement <DbActSecurityPolicy>().SelectFrom(typeof(DbSecurityPolicy), typeof(DbActSecurityPolicy)) .AutoJoin <DbSecurityPolicy, DbActSecurityPolicy>() .Where(o => o.SourceKey == pAct.Key); result = context.Query <CompositeResult <DbSecurityPolicy, DbActSecurityPolicy> >(query) .AsEnumerable().Select(o => new AdoSecurityPolicyInstance(o.Object2, o.Object1, securable)).ToList(); } else if (securable is Core.Model.Entities.Entity pEntity) { var query = context.CreateSqlStatement <DbEntitySecurityPolicy>().SelectFrom(typeof(DbSecurityPolicy), typeof(DbEntitySecurityPolicy)) .AutoJoin <DbSecurityPolicy, DbEntitySecurityPolicy>() .Where(o => o.SourceKey == pEntity.Key); result = context.Query <CompositeResult <DbSecurityPolicy, DbEntitySecurityPolicy> >(query) .AsEnumerable().Select(o => new AdoSecurityPolicyInstance(o.Object2, o.Object1, securable)).ToList(); } else if (securable is SecurityUser pUser) { // Join for policies var query = context.CreateSqlStatement <DbSecurityUserRole>().SelectFrom(typeof(DbSecurityPolicy), typeof(DbSecurityRolePolicy)) .InnerJoin <DbSecurityUserRole, DbSecurityRolePolicy>( o => o.RoleKey, o => o.SourceKey ) .InnerJoin <DbSecurityRolePolicy, DbSecurityPolicy>( o => o.PolicyKey, o => o.Key ) .Where <DbSecurityUserRole>(o => o.UserKey == pUser.Key); result = context.Query <CompositeResult <DbSecurityPolicy, DbSecurityRolePolicy> >(query) .AsEnumerable().Select(o => new AdoSecurityPolicyInstance(o.Object2, o.Object1, securable)).ToList(); } else { result = new List <AdoSecurityPolicyInstance>(); } } catch (Exception e) { this.m_traceSource.TraceEvent(EventLevel.Error, "Error getting active policies for {0} : {1}", securable, e); throw new Exception($"Error getting active policies for {securable}", e); } } } return(result); }
/// <summary> /// Hack query builder based on clause /// </summary> public bool HackQuery(QueryBuilder builder, SqlStatement sqlStatement, SqlStatement whereClause, Type tmodel, PropertyInfo property, string queryPrefix, QueryPredicate predicate, object values, IEnumerable <TableMapping> scopedTables, params KeyValuePair <String, object>[] queryFilter) { string columnName = String.Empty; Type scanType = null; // Filter values if (typeof(Concept).IsAssignableFrom(property.PropertyType) && predicate.SubPath == "mnemonic") { Regex removeRegex = null; if (predicate.Path == "participationRole" && property.DeclaringType == typeof(ActParticipation)) { columnName = "rol_cd_id"; scanType = typeof(ActParticipationKey); // We want to remove the inner join for cd_tbl removeRegex = new Regex(@"INNER\sJOIN\scd_tbl\s.*\(.*?rol_cd_id.*"); } else if (predicate.Path == "relationshipType" && property.DeclaringType == typeof(EntityRelationship)) { columnName = "rel_typ_cd_id"; scanType = typeof(EntityRelationshipTypeKeys); removeRegex = new Regex(@"INNER\sJOIN\scd_tbl\s.*\(.*?rel_typ_cd_id.*"); } else if (predicate.Path == "relationshipType" && property.DeclaringType == typeof(ActRelationship)) { columnName = "rel_typ_cd_id"; scanType = typeof(ActRelationshipTypeKeys); removeRegex = new Regex(@"INNER\sJOIN\scd_tbl\s.*\(.*?rel_typ_cd_id.*"); } else { return(false); } // Now we scan List <Object> qValues = new List <object>(); if (values is IEnumerable) { foreach (var i in values as IEnumerable) { var fieldInfo = scanType.GetRuntimeField(i.ToString()); if (fieldInfo == null) { return(false); } qValues.Add(fieldInfo.GetValue(null)); } } else { var fieldInfo = scanType.GetRuntimeField(values.ToString()); if (fieldInfo == null) { return(false); } qValues.Add(fieldInfo.GetValue(null)); } // Now add to query whereClause.And($"{columnName} IN ({String.Join(",", qValues.Select(o=>$"'{o}'").ToArray())})"); // Remove the inner join var remStack = new Stack <SqlStatement>(); SqlStatement last; while (sqlStatement.RemoveLast(out last)) { var m = removeRegex.Match(last.SQL); if (m.Success) { // The last thing we added was the if (m.Index == 0 && m.Length == last.SQL.Length) { remStack.Pop(); } else { sqlStatement.Append(last.SQL.Remove(m.Index, m.Length), last.Arguments.ToArray()); } break; } else { remStack.Push(last); } } while (remStack.Count > 0) { sqlStatement.Append(remStack.Pop()); } return(true); } else { return(false); } }
/// <summary> /// Hack the query /// </summary> public bool HackQuery(QueryBuilder builder, SqlStatement sqlStatement, SqlStatement whereClause, Type tmodel, PropertyInfo property, string queryPrefix, QueryPredicate predicate, object values, IEnumerable <TableMapping> scopedTables, params KeyValuePair <String, object>[] queryFilter) { String cmpTblType = String.Empty, valTblType = String.Empty, keyName = String.Empty; Type guardType = null, componentType = null; // We can attempt to hack the address if (typeof(EntityAddress).IsAssignableFrom(tmodel)) { cmpTblType = "ent_addr_cmp_tbl"; valTblType = "ent_addr_cmp_val_tbl"; guardType = typeof(AddressComponentKeys); componentType = typeof(EntityAddressComponent); keyName = "addr_id"; } else if (typeof(EntityName).IsAssignableFrom(tmodel)) { cmpTblType = "ent_name_cmp_tbl"; valTblType = "phon_val_tbl"; guardType = typeof(NameComponentKeys); componentType = typeof(EntityNameComponent); keyName = "name_id"; } else { return(false); } // Not applicable for us if // - Not a name or address // - Predicate is not component.value // - There is already other where clause stuff if (guardType == null || predicate.Path != "component" || predicate.SubPath != "value" || !String.IsNullOrEmpty(whereClause.SQL)) { return(false); } whereClause.And($" {keyName} IN (SELECT {keyName} FROM {cmpTblType} AS {queryPrefix}{cmpTblType} "); // Filter through other name or address components which may be in the query at this query level List <String> componentTypeGuard = new List <String>(); var localChar = 'a'; int vCount = 0; foreach (var itm in queryFilter) { var pred = QueryPredicate.Parse(itm.Key); String guardFilter = String.Empty; // Do we have a guard for address? if (!String.IsNullOrEmpty(pred.Guard)) { // Translate Guards to UUIDs var guards = pred.Guard.Split('|'); for (int i = 0; i < guards.Length; i++) { guards[i] = guardType.GetField(guards[i]).GetValue(null).ToString(); } if (guards.Any(o => o == null)) { return(false); } // Add to where clause componentTypeGuard.AddRange(guards); guardFilter = $"AND {queryPrefix}{cmpTblType}.typ_cd_id IN ({String.Join(",", guards.Select(o => $"'{o}'"))})"; } // Filter on the component value var value = itm.Value; if (value is String) { value = new List <Object>() { value } } ; var qValues = value as List <Object>; vCount++; whereClause.Append($"LEFT JOIN (SELECT val_seq_id FROM {valTblType} AS {queryPrefix}{valTblType} WHERE "); whereClause.Append(builder.CreateSqlPredicate($"{queryPrefix}{valTblType}", "val", componentType.GetProperty("Value"), qValues)); whereClause.Append($") AS {queryPrefix}{valTblType}_{localChar} ON ({queryPrefix}{valTblType}_{localChar++}.val_seq_id = {queryPrefix}{cmpTblType}.val_seq_id {guardFilter})"); } whereClause.Append($" WHERE "); if (componentTypeGuard.Count > 0) { whereClause.Append($"{queryPrefix}{cmpTblType}.typ_cd_id IN ({String.Join(",", componentTypeGuard.Select(o => $"'{o}'"))}) AND "); } whereClause.Append("("); // Ensure that the left joined objects exist for (char s = 'a'; s < localChar; s++) { whereClause.Append($" {queryPrefix}{valTblType}_{s}.val_seq_id IS NOT NULL ").Append("OR"); } whereClause.RemoveLast(); whereClause.Append($") GROUP BY {keyName} HAVING COUNT(DISTINCT {queryPrefix}{cmpTblType}.cmp_id) >= {vCount})"); return(true); } }
/// <summary> /// Hack the query /// </summary> public bool HackQuery(QueryBuilder builder, SqlStatement sqlStatement, SqlStatement whereClause, Type tmodel, PropertyInfo property, string queryPrefix, QueryPredicate predicate, object values, IEnumerable <TableMapping> scopedTables, params KeyValuePair <String, object>[] queryFilter) { String cmpTblType = String.Empty, valTblType = String.Empty, keyName = String.Empty; Type guardType = null, componentType = null; // We can attempt to hack the address if (typeof(EntityAddress).IsAssignableFrom(tmodel)) { cmpTblType = "ent_addr_cmp_tbl"; valTblType = "ent_addr_cmp_val_tbl"; guardType = typeof(AddressComponentKeys); componentType = typeof(EntityAddressComponent); keyName = "addr_id"; } else if (typeof(EntityName).IsAssignableFrom(tmodel)) { cmpTblType = "ent_name_cmp_tbl"; valTblType = "phon_val_tbl"; guardType = typeof(NameComponentKeys); componentType = typeof(EntityNameComponent); keyName = "name_id"; } else { return(false); } // Not applicable for us if // - Not a name or address // - Predicate is not component.value // - There is already other where clause stuff if (guardType == null || predicate.Path != "component" || predicate.SubPath != "value" || !String.IsNullOrEmpty(whereClause.SQL)) { return(false); } // Pop the last statement off // var fromClause = sqlStatement.RemoveLast(); var subQueryAlias = $"{queryPrefix}{scopedTables.First().TableName}"; whereClause.And($" {subQueryAlias}.{keyName} IN ("); foreach (var itm in queryFilter) { var pred = QueryPredicate.Parse(itm.Key); String guardFilter = String.Empty; // Do we have a guard for address? if (!String.IsNullOrEmpty(pred.Guard)) { // Translate Guards to UUIDs var guards = pred.Guard.Split('|'); for (int i = 0; i < guards.Length; i++) { guards[i] = guardType.GetField(guards[i]).GetValue(null).ToString(); } if (guards.Any(o => o == null)) { return(false); } // Add to where clause guardFilter = $"AND {queryPrefix}{cmpTblType}.typ_cd_id IN ({String.Join(",", guards.Select(o => $"'{o}'"))}) "; } // Filter on the component value var value = itm.Value; if (value is String) { value = new List <Object>() { value } } ; var qValues = value as List <Object>; // Filter based on type and prefix :) whereClause .Append($" SELECT {queryPrefix}{cmpTblType}.{keyName} ") .Append($" FROM {cmpTblType} AS {queryPrefix}{cmpTblType} ") .Append(" WHERE ") .Append($" val_seq_id IN (SELECT val_seq_id FROM {valTblType} WHERE ") .Append(builder.CreateSqlPredicate($"{valTblType}", "val", componentType.GetProperty("Value"), qValues)) .Append(") ") .Append(guardFilter) .Append(" INTERSECT "); } whereClause.RemoveLast(); whereClause.Append($") "); whereClause.And($"{subQueryAlias}.obslt_vrsn_seq_id IS NULL "); return(true); } }