private static QueryGroup ParseContainsForArrayOrList <TEntity>(MethodCallExpression expression, bool isNot, bool isEqualsTo) where TEntity : class { // Return null if there is no any arguments if (expression.Arguments?.Any() != true) { return(null); } // Get the last arg var last = expression .Arguments .LastOrDefault(); // Make sure the last arg is a member if (last == null || last?.IsMember() == false) { throw new NotSupportedException($"Expression '{expression.ToString()}' is currently not supported."); } // Make sure it is a property info var member = last.ToMember().Member; if (member.IsPropertyInfo() == false) { throw new NotSupportedException($"Expression '{expression.ToString()}' is currently not supported."); } // Get the property var property = member.ToPropertyInfo(); // Make sure the property is in the entity if (PropertyCache.Get <TEntity>().FirstOrDefault(p => p.PropertyInfo == property) == null) { throw new InvalidQueryExpressionException($"Invalid expression '{expression.ToString()}'. The property {property.Name} is not defined on a target type '{typeof(TEntity).FullName}'."); } // Get the values var values = (object)null; // Array/List Separation if (expression.Object == null) { // Expecting an array values = expression.Arguments.First().GetValue(); } else { // Expecting a list here values = expression.Object.GetValue(); // Convert to a proper array type if ((values is Array) == false) { values = values.AsArray(); } } // Add to query fields var operation = (isNot == false && isEqualsTo == true) ? Operation.In : Operation.NotIn; var queryField = new QueryField(PropertyMappedNameCache.Get(property, true), operation, values); // Return the result var queryGroup = new QueryGroup(queryField); // Set the IsNot value queryGroup.SetIsNot(isNot == true && isEqualsTo == false); // Return the instance return(queryGroup); }
static GetPropertiesValuesCache() { m_func = GetFunc(PropertyCache.Get <TEntity>()); }
/// <summary> /// Appends a stringified fields to the SQL Query Statement. /// </summary> /// <typeparam name="TEntity">The type of data entity object bound for the SQL Statement to be created.</typeparam> /// <param name="dbSetting">The currently in used <see cref="IDbSetting"/> object.</param> /// <returns>The current instance.</returns> public QueryBuilder FieldsFrom <TEntity>(IDbSetting dbSetting) where TEntity : class { return(FieldsFrom(PropertyCache.Get <TEntity>()?.AsFields(), dbSetting)); }
/// <summary> /// Append the stringified parameter as fields to the SQL Query Statement based on the mapped command. /// </summary> /// <param name="command">The command where the mapping is defined.</param> /// <returns>The current instance.</returns> public QueryBuilder <TEntity> ParametersAsFieldsFrom(Command command) { var fields = PropertyCache.Get <TEntity>(command)?.Select(property => property.GetMappedName()); return(Append(fields?.AsParametersAsFields().Join(", "))); }
private static QueryGroup ParseAllOrAnyForArray <TEntity>(MethodCallExpression expression, bool isNot = false, bool isEqualsTo = true) where TEntity : class { // Return null if there is no any arguments if (expression.Arguments?.Any() == false) { return(null); } // Get the last property var last = expression .Arguments .LastOrDefault(); // Make sure the last is a member if (last == null || last?.IsLambda() == false) { throw new NotSupportedException($"Expression '{expression.ToString()}' is currently not supported."); } // Make sure the last is a binary var lambda = last.ToLambda(); if (lambda.Body.IsBinary() == false) { throw new NotSupportedException($"Expression '{expression.ToString()}' is currently not supported."); } // Make sure it is a member var binary = lambda.Body.ToBinary(); if (binary.Left.IsMember() == false && binary.Right.IsMember() == false) { throw new NotSupportedException($"Expression '{expression.ToString()}' is currently not supported. Expression must contain a single condition to any property of type '{typeof(TEntity).FullName}'."); } // Make sure it is a property var member = binary.Left.IsMember() ? binary.Left.ToMember().Member : binary.Right.ToMember().Member; if (member.IsPropertyInfo() == false) { throw new NotSupportedException($"Expression '{expression.ToString()}' is currently not supported."); } // Make sure the property is in the entity var property = member.ToPropertyInfo(); if (PropertyCache.Get <TEntity>().FirstOrDefault(p => p.PropertyInfo == property) == null) { throw new InvalidQueryExpressionException($"Invalid expression '{expression.ToString()}'. The property {property.Name} is not defined on a target type '{typeof(TEntity).FullName}'."); } // Variables needed for fields var queryFields = new List <QueryField>(); var conjunction = Conjunction.And; // Support only various methods if (expression.Method.Name == StringConstant.Any) { conjunction = Conjunction.Or; } else if (expression.Method.Name == StringConstant.All) { conjunction = Conjunction.And; } // Call the method var first = expression.Arguments.First(); var values = (object)null; // Identify the type of the argument if (first.IsNewArray()) { values = first.ToNewArray().GetValue(); } else if (first.IsMember()) { values = first.ToMember().GetValue(); } // Values must be an array if (values is Array) { var operation = QueryField.GetOperation(binary.NodeType); foreach (var value in (Array)values) { queryFields.Add(new QueryField(property.Name, operation, value)); } } // Return the result return(new QueryGroup(queryFields, null, conjunction, (isNot == isEqualsTo))); }
/// <summary> /// Appends a stringified fields to the SQL Query Statement by command. /// </summary> /// <param name="command">The mapped command where to get all the fields to be stringified.</param> /// <returns>The current instance.</returns> public QueryBuilder <TEntity> FieldsFrom(Command command) { var fields = PropertyCache.Get <TEntity>(command)?.Select(property => property.GetMappedName().AsQuoted(true)); return(Append(fields?.ToList().AsFields().Join(", "))); }
/// <summary> /// Appends a stringified fields to the SQL Query Statement by command with aliases. /// </summary> /// <param name="command">The mapped command where to get all the fields to be stringified.</param> /// <param name="alias">The alias to be prepended for each field.</param> /// <returns>The current instance.</returns> public QueryBuilder <TEntity> AsAliasFieldsFrom(Command command, string alias) { var fields = PropertyCache.Get <TEntity>(command)?.Select(property => property.GetMappedName()); return(Append(fields?.AsAliasFields(alias).Join(", "))); }
static ClassPropertyValuesExtractorForUpdate() { m_func = GetCompiledFunctionForClassPropertyValuesExtractor <T>(PropertyCache.Get <T>(Command.Update)); }
/// <summary> /// /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="connection"></param> /// <param name="tableName"></param> /// <param name="entities"></param> /// <param name="qualifiers"></param> /// <param name="mappings"></param> /// <param name="bulkCopyTimeout"></param> /// <param name="batchSize"></param> /// <param name="keepIdentity"></param> /// <param name="pseudoTableType"></param> /// <param name="transaction"></param> /// <returns></returns> private static int BinaryBulkUpdateBase <TEntity>(this NpgsqlConnection connection, string tableName, IEnumerable <TEntity> entities, IEnumerable <Field> qualifiers = null, IEnumerable <NpgsqlBulkInsertMapItem> mappings = null, int?bulkCopyTimeout = null, int?batchSize = null, bool keepIdentity = false, BulkImportPseudoTableType pseudoTableType = default, NpgsqlTransaction transaction = null) where TEntity : class { var entityType = entities?.First()?.GetType() ?? typeof(TEntity); // Solving the anonymous types var isDictionary = entityType.IsDictionaryStringObject(); var dbSetting = connection.GetDbSetting(); var dbFields = DbFieldCache.Get(connection, tableName, transaction); var pseudoTableName = tableName; var identityBehavior = keepIdentity ? BulkImportIdentityBehavior.KeepIdentity : BulkImportIdentityBehavior.Unspecified; return(PseudoBasedBinaryImport(connection, tableName, bulkCopyTimeout, dbFields, // getPseudoTableName () => pseudoTableName = GetBinaryBulkUpdatePseudoTableName(tableName ?? ClassMappedNameCache.Get <TEntity>(), dbSetting), // getMappings () => { var includeIdentity = identityBehavior == BulkImportIdentityBehavior.KeepIdentity; var includePrimary = true; return mappings = mappings?.Any() == true ? mappings : isDictionary ? GetMappings(entities?.First() as IDictionary <string, object>, dbFields, includePrimary, includeIdentity, dbSetting) : GetMappings(dbFields, PropertyCache.Get(entityType), includePrimary, includeIdentity, dbSetting); }, // binaryImport (tableName) => connection.BinaryImport <TEntity>(tableName, entities, mappings, dbFields, bulkCopyTimeout, batchSize, identityBehavior, dbSetting, transaction), // getUpdateToPseudoCommandText () => GetUpdateCommandText(pseudoTableName, tableName, mappings.Select(mapping => new Field(mapping.DestinationColumn)), qualifiers, dbFields.FirstOrDefault(dbField => dbField.IsPrimary)?.AsField(), dbFields.FirstOrDefault(dbField => dbField.IsIdentity)?.AsField(), identityBehavior, dbSetting), // setIdentities (identityResults) => SetIdentities(entityType, entities, dbFields, identityResults, dbSetting), qualifiers, false, identityBehavior, pseudoTableType, dbSetting, transaction)); }
static ClassPropertyValuesExtractorForQuery() { m_func = GetCompiledFunctionForClassPropertyValuesExtractor <T>(PropertyCache.Get <T>(Command.Query)); }
static ClassPropertyValuesExtractorForInlineMerge() { m_func = GetCompiledFunctionForClassPropertyValuesExtractor <T>(PropertyCache.Get <T>(Command.InlineMerge)); }
static ClassPropertyValuesExtractorForDeleteAll() { m_func = GetCompiledFunctionForClassPropertyValuesExtractor <T>(PropertyCache.Get <T>(Command.DeleteAll)); }
static ClassPropertyValuesExtractorForBulkInsert() { m_func = GetCompiledFunctionForClassPropertyValuesExtractor <T>(PropertyCache.Get <T>(Command.BulkInsert)); }
static ClassPropertyValuesExtractor() { m_func = GetCompiledFunctionForClassPropertyValuesExtractor <T>(PropertyCache.Get <T>()); }