示例#1
0
        /// <summary>
        /// Gets the list of <see cref="DbField"/> of the table in an asychronous way.
        /// </summary>
        /// <param name="connection">The instance of the connection object.</param>
        /// <param name="tableName">The name of the target table.</param>
        /// <param name="transaction">The transaction object that is currently in used.</param>
        /// <returns>A list of <see cref="DbField"/> of the target table.</returns>
        public async Task <IEnumerable <DbField> > GetFieldsAsync(IDbConnection connection,
                                                                  string tableName,
                                                                  IDbTransaction transaction = null)
        {
            // Variables
            var commandText = GetCommandText();
            var param       = new
            {
                TableSchema = connection.Database,
                TableName   = DataEntityExtension.GetTableName(tableName, m_dbSetting)
            };

            // Iterate and extract
            using (var reader = await connection.ExecuteReaderAsync(commandText, param, transaction: transaction))
            {
                var dbFields = new List <DbField>();

                // Iterate the list of the fields
                while (reader.Read())
                {
                    dbFields.Add(ReaderToDbField(reader));
                }

                // Return the list of fields
                return(dbFields);
            }
        }
示例#2
0
        /// <summary>
        /// Gets the list of <see cref="DbField"/> of the table.
        /// </summary>
        /// <param name="connection">The instance of the connection object.</param>
        /// <param name="tableName">The name of the target table.</param>
        /// <param name="transaction">The transaction object that is currently in used.</param>
        /// <returns>A list of <see cref="DbField"/> of the target table.</returns>
        public IEnumerable <DbField> GetFields(IDbConnection connection,
                                               string tableName,
                                               IDbTransaction transaction = null)
        {
            // Variables
            var commandText = GetCommandText();
            var setting     = connection.GetDbSetting();
            var param       = new
            {
                Schema    = DataEntityExtension.GetSchema(tableName, setting),
                TableName = DataEntityExtension.GetTableName(tableName, setting)
            };

            // Iterate and extract
            using (var reader = (DbDataReader)connection.ExecuteReader(commandText, param, transaction: transaction))
            {
                var dbFields = new List <DbField>();

                // Iterate the list of the fields
                while (reader.Read())
                {
                    dbFields.Add(ReaderToDbField(reader));
                }

                // Return the list of fields
                return(dbFields);
            }
        }
示例#3
0
        /// <summary>
        /// Creates a SQL Statement for repository <i>Insert</i> operation that is meant for SQL Server.
        /// </summary>
        /// <typeparam name="TEntity">
        /// The <i>DataEntity</i> object bound for the SQL Statement to be created.
        /// </typeparam>
        /// <param name="queryBuilder">An instance of query builder used to build the SQL statement.</param>
        /// <param name="isPrimaryIdentity">A boolean value indicates whether the primary key is identity in the database.</param>
        /// <returns>A string containing the composed SQL Statement for <i>Insert</i> operation.</returns>
        internal string CreateInsert <TEntity>(QueryBuilder <TEntity> queryBuilder, bool isPrimaryIdentity)
            where TEntity : DataEntity
        {
            var primary = DataEntityExtension.GetPrimaryProperty <TEntity>();
            var fields  = DataEntityExtension.GetPropertiesFor <TEntity>(Command.Insert)
                          .Where(property => !(isPrimaryIdentity && property == primary))
                          .Select(p => new Field(p.Name));

            // Build the SQL Statement
            queryBuilder = queryBuilder ?? new QueryBuilder <TEntity>();
            queryBuilder
            .Clear()
            .Insert()
            .Into()
            .TableFrom(Command.Insert)
            .OpenParen()
            .FieldsFrom(fields)
            .CloseParen()
            .Values()
            .OpenParen()
            .ParametersFrom(fields)
            .CloseParen()
            .End();
            var result = isPrimaryIdentity ? "SCOPE_IDENTITY()" : (primary != null) ? $"@{primary.GetMappedName()}" : "NULL";

            queryBuilder
            .Select()
            .WriteText(result)
            .As("[Result]")
            .End();

            // Return the query
            return(queryBuilder.GetString());
        }
        /// <summary>
        /// Creates a SQL Statement for repository <i>Update</i> operation that is meant for SQL Server.
        /// </summary>
        /// <typeparam name="TEntity">
        /// The <i>DataEntity</i> object bound for the SQL Statement to be created.
        /// </typeparam>
        /// <param name="queryBuilder">An instance of query builder used to build the SQL statement.</param>
        /// <param name="where">The query expression for SQL statement.</param>
        /// <returns>A string containing the composed SQL Statement for <i>Update</i> operation.</returns>
        public string CreateUpdate <TEntity>(QueryBuilder <TEntity> queryBuilder, QueryGroup where)
            where TEntity : DataEntity
        {
            var properties = DataEntityExtension.GetPropertiesFor <TEntity>(Command.Update);

            if (properties?.Any() == false)
            {
                throw new InvalidOperationException($"No updateable fields found from type '{typeof(TEntity).FullName}'.");
            }
            var primary  = DataEntityExtension.GetPrimaryProperty <TEntity>();
            var identity = DataEntityExtension.GetIdentityProperty <TEntity>();

            if (identity != null && identity != primary)
            {
                throw new InvalidOperationException($"Identity property must be the primary property for type '{typeof(TEntity).FullName}'.");
            }
            var fields = properties
                         .Where(property => property != primary && property != identity)
                         .Select(p => new Field(p.GetMappedName()));

            where?.AppendParametersPrefix();
            queryBuilder = queryBuilder ?? new QueryBuilder <TEntity>();
            queryBuilder
            .Clear()
            .Update()
            .TableFrom(Command.Update)
            .Set()
            .FieldsAndParametersFrom(fields)
            .WhereFrom(where)
            .End();
            return(queryBuilder.GetString());
        }
示例#5
0
        /// <summary>
        /// Gets the list of <see cref="DbField"/> of the table in an asynchronous way.
        /// </summary>
        /// <param name="connection">The instance of the connection object.</param>
        /// <param name="tableName">The name of the target table.</param>
        /// <param name="transaction">The transaction object that is currently in used.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> object to be used during the asynchronous operation.</param>
        /// <returns>A list of <see cref="DbField"/> of the target table.</returns>
        public async Task <IEnumerable <DbField> > GetFieldsAsync(IDbConnection connection,
                                                                  string tableName,
                                                                  IDbTransaction transaction          = null,
                                                                  CancellationToken cancellationToken = default)
        {
            // Variables
            var commandText = GetCommandText();
            var setting     = connection.GetDbSetting();
            var param       = new
            {
                Schema    = DataEntityExtension.GetSchema(tableName, setting),
                TableName = DataEntityExtension.GetTableName(tableName, setting)
            };

            // Iterate and extract
            using (var reader = (DbDataReader)await connection.ExecuteReaderAsync(commandText, param,
                                                                                  transaction: transaction, cancellationToken: cancellationToken))
            {
                var dbFields = new List <DbField>();

                // Iterate the list of the fields
                while (await reader.ReadAsync(cancellationToken))
                {
                    dbFields.Add(await ReaderToDbFieldAsync(reader, cancellationToken));
                }

                // Return the list of fields
                return(dbFields);
            }
        }
示例#6
0
        /// <summary>
        /// Gets the list of <see cref="DbField"/> of the table in an asychronous way.
        /// </summary>
        /// <param name="connection">The instance of the connection object.</param>
        /// <param name="tableName">The name of the target table.</param>
        /// <param name="transaction">The transaction object that is currently in used.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> object to be used during the asynchronous operation.</param>
        /// <returns>A list of <see cref="DbField"/> of the target table.</returns>
        public async Task <IEnumerable <DbField> > GetFieldsAsync(IDbConnection connection,
                                                                  string tableName,
                                                                  IDbTransaction transaction          = null,
                                                                  CancellationToken cancellationToken = default)
        {
            cancellationToken.ThrowIfCancellationRequested();

            // Variables
            var commandText = GetCommandText();
            var param       = new
            {
                TableSchema = connection.Database,
                TableName   = DataEntityExtension.GetTableName(tableName, m_dbSetting)
            };

            // Iterate and extract
            using (var reader = (DbDataReader)await connection.ExecuteReaderAsync(commandText, param, transaction: transaction,
                                                                                  cancellationToken: cancellationToken))
            {
                var dbFields = new List <DbField>();

                // Iterate the list of the fields
                while (await reader.ReadAsync(cancellationToken))
                {
                    // The 'ReaderToDbFieldAsync' is having a bad behavior on different versions
                    // of MySQL for this driver (from Oracle). Also, the 'CAST' and 'CONVERT' is
                    // not working on our DEVENV.
                    // dbFields.Add(await ReaderToDbFieldAsync(reader, cancellationToken));
                    dbFields.Add(ReaderToDbField(reader));
                }

                // Return the list of fields
                return(dbFields);
            }
        }
示例#7
0
            private static Func <IEnumerable <ClassProperty> > GetFunc()
            {
                var body = Expression.Constant(DataEntityExtension.GetProperties <TEntity>());

                return(Expression
                       .Lambda <Func <IEnumerable <ClassProperty> > >(body)
                       .Compile());
            }
示例#8
0
        public void TestMapAttributeName()
        {
            // Act
            var actual   = DataEntityExtension.GetMappedName <TestMapAttributeNameClass>();
            var expected = "Name";

            // Assert
            Assert.AreEqual(expected, actual);
        }
        public void TestDataEntityExtensionGetSchemaFromQuotedAndIsWhitespaced()
        {
            // Prepare
            var dbSetting = new CustomDbSetting();

            // Act
            var schema = DataEntityExtension.GetSchema("[Schema Name].[TableName]", dbSetting);

            // Assert
            Assert.AreEqual("[Schema Name]", schema);
        }
        public void TestDataEntityExtensionGetTableName()
        {
            // Prepare
            var dbSetting = new CustomDbSetting();

            // Act
            var schema = DataEntityExtension.GetTableName("TableName", dbSetting);

            // Assert
            Assert.AreEqual("TableName", schema);
        }
示例#11
0
        /// <summary>
        /// Gets the cached mapped-name for the entity.
        /// </summary>
        /// <param name="type">The type of the target entity.</param>
        /// <returns>The cached mapped name of the entity.</returns>
        internal static string Get(Type type)
        {
            var key    = type.FullName;
            var result = (string)null;

            if (m_cache.TryGetValue(key, out result) == false)
            {
                result = DataEntityExtension.GetMappedName(type);
                m_cache.TryAdd(key, result);
            }
            return(result);
        }
示例#12
0
        /// <summary>
        /// Gets the cached mapped-name for the entity.
        /// </summary>
        /// <param name="type">The type of the target entity.</param>
        /// <param name="command">The target command.</param>
        /// <returns>The cached command type of the entity.</returns>
        internal static string Get(Type type, Command command = Command.None)
        {
            var key    = $"{type.FullName}.{command.ToString()}";
            var result = (string)null;

            if (m_cache.TryGetValue(key, out result) == false)
            {
                result = DataEntityExtension.GetMappedName(type, command);
                m_cache.TryAdd(key, result);
            }
            return(result);
        }
        /// <summary>
        /// Gets a function used to extract the properties of a class.
        /// </summary>
        /// <typeparam name="T">The target type.</typeparam>
        /// <returns>The properties of the class.</returns>
        private static Func <IEnumerable <ClassProperty> > GetCompiledFunctionForClassPropertiesExtractor <T>()
            where T : class
        {
            // Variables type (Command.None is preloaded everywhere)
            var properties = DataEntityExtension.GetProperties <T>();

            // Set the body
            var body = Expression.Constant(properties);

            // Set the function value
            return(Expression
                   .Lambda <Func <IEnumerable <ClassProperty> > >(body)
                   .Compile());
        }
示例#14
0
        /// <summary>
        /// Creates a SQL Statement for repository <i>Merge</i> operation that is meant for SQL Server.
        /// </summary>
        /// <typeparam name="TEntity">
        /// The <i>DataEntity</i> object bound for the SQL Statement to be created.
        /// </typeparam>
        /// <param name="queryBuilder">An instance of query builder used to build the SQL statement.</param>
        /// <param name="qualifiers">The list of qualifier fields to be used for the <i>Merge</i> operation in SQL Statement composition.</param>
        /// <returns>A string containing the composed SQL Statement for <i>Merge</i> operation.</returns>
        public string CreateMerge <TEntity>(QueryBuilder <TEntity> queryBuilder, IEnumerable <Field> qualifiers)
            where TEntity : DataEntity
        {
            var primary  = DataEntityExtension.GetPrimaryProperty <TEntity>();
            var identity = DataEntityExtension.GetIdentityProperty <TEntity>();

            if (identity != null && identity != primary)
            {
                throw new InvalidOperationException($"Identity property must be the primary property for type '{typeof(TEntity).FullName}'.");
            }
            var isPrimaryIdentity = (identity != null) && identity == primary;

            return(CreateMerge(queryBuilder, qualifiers, isPrimaryIdentity));
        }
示例#15
0
        /// <summary>
        /// Creates a SQL Statement for repository <i>InlineInsert</i> operation.
        /// </summary>
        /// <typeparam name="TEntity">
        /// The <i>DataEntity</i> object bound for the SQL Statement to be created.
        /// </typeparam>
        /// <param name="queryBuilder">An instance of query builder used to build the SQL statement.</param>
        /// <param name="fields">The list of the fields to be a part of the inline insert operation in SQL Statement composition.</param>
        /// <param name="overrideIgnore">
        /// Set to <i>true</i> if the defined <i>RepoDb.Attributes.IgnoreAttribute</i> would likely
        /// be ignored on the inline insert operation in SQL Statement composition.
        /// </param>
        /// <returns>A string containing the composed SQL Statement for <i>InlineInsert</i> operation.</returns>
        public string CreateInlineInsert <TEntity>(QueryBuilder <TEntity> queryBuilder, IEnumerable <Field> fields, bool?overrideIgnore = false)
            where TEntity : DataEntity
        {
            var primary  = DataEntityExtension.GetPrimaryProperty <TEntity>();
            var identity = DataEntityExtension.GetIdentityProperty <TEntity>();

            if (identity != null && identity != primary)
            {
                throw new InvalidOperationException($"Identity property must be the primary property for type '{typeof(TEntity).FullName}'.");
            }
            var isPrimaryIdentity = (identity != null) && identity == primary;

            return(CreateInlineInsert <TEntity>(queryBuilder, fields, overrideIgnore, isPrimaryIdentity));
        }
示例#16
0
        /// <summary>
        /// Gets the cached command type for the entity.
        /// </summary>
        /// <typeparam name="TEntity">The type of the target entity.</typeparam>
        /// <param name="command">The target command.</param>
        /// <returns>The cached command type of the entity.</returns>
        public static CommandType Get <TEntity>(Command command = Command.None)
            where TEntity : class
        {
            var type   = typeof(TEntity);
            var key    = $"{type.FullName}.{command.ToString()}";
            var result = CommandType.Text;

            if (m_cache.TryGetValue(key, out result) == false)
            {
                result = DataEntityExtension.GetCommandType <TEntity>(command);
                m_cache.TryAdd(key, result);
            }
            return(result);
        }
示例#17
0
        /// <summary>
        /// Gets a delegate that is used to convert the <i>System.Data.Common.DbDataReader</i> object into <i>RepoDb.DataEntity</i> object.
        /// </summary>
        /// <typeparam name="TEntity">The <i>RepoDb.DataEntity</i> object to convert to.</typeparam>
        /// <param name="reader">The <i>System.Data.Common.DbDataReader</i> to be converted.</param>
        /// <returns>An instance of <i>RepoDb.DataEntity</i> object.</returns>
        public static DataReaderToDataEntityDelegate <TEntity> GetDataReaderToDataEntityDelegate <TEntity>(DbDataReader reader) where TEntity : DataEntity
        {
            var entityType    = typeof(TEntity);
            var dynamicMethod = new DynamicMethod(StringConstant.DynamicMethod,
                                                  entityType,
                                                  new[] { typeof(DbDataReader) },
                                                  typeof(Assembly).Module,
                                                  true);
            var ilGenerator = dynamicMethod.GetILGenerator();

            // Declare IL Variables
            ilGenerator.DeclareLocal(entityType);
            ilGenerator.DeclareLocal(typeof(object));

            // Create instance of the object type
            ilGenerator.Emit(OpCodes.Newobj, entityType.GetConstructor(Type.EmptyTypes));
            ilGenerator.Emit(OpCodes.Stloc, 0);

            // Matching the fields
            var fields       = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList();
            var matchedCount = 0;

            // Iterate the properties
            DataEntityExtension.GetPropertiesFor <TEntity>(Command.Query)
            .Where(property => property.CanWrite)
            .ToList()
            .ForEach(property =>
            {
                var ordinal = fields.IndexOf(property.GetMappedName());
                if (ordinal >= 0)
                {
                    EmitDataReaderToDataEntityMapping <TEntity>(ilGenerator, ordinal, property);
                    matchedCount++;
                }
            });

            // Throw an error if there are no matching atleast one
            if (matchedCount == 0)
            {
                throw new NoMatchedFieldsException($"There is no matching fields between the result set of the data reader and the type '{typeof(TEntity).FullName}'.");
            }

            // Return the TEntity instance value
            ilGenerator.Emit(OpCodes.Ldloc, 0);
            ilGenerator.Emit(OpCodes.Ret);

            // Create a delegate
            return((DataReaderToDataEntityDelegate <TEntity>)dynamicMethod.CreateDelegate(typeof(DataReaderToDataEntityDelegate <TEntity>)));
        }
示例#18
0
        /// <summary>
        /// Gets the cached mapped-name for the entity.
        /// </summary>
        /// <param name="type">The type of the target entity.</param>
        /// <returns>The cached mapped name of the entity.</returns>
        internal static string Get(Type type)
        {
            var key    = type.FullName.GetHashCode();
            var result = (string)null;

            // Try get the value
            if (m_cache.TryGetValue(key, out result) == false)
            {
                result = DataEntityExtension.GetMappedName(type);
                m_cache.TryAdd(key, result);
            }

            // Return the value
            return(result);
        }
示例#19
0
        /// <summary>
        /// Checks whether the column is identity.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connectionString">The connection string object to be used.</param>
        /// <param name="command">The target command.</param>
        /// <param name="columnName">The name of the column.</param>
        /// <returns>A boolean value indicating the identification of the column.</returns>
        public static bool IsIdentity <T>(string connectionString, Command command, string columnName)
            where T : DataEntity
        {
            var isIdentity = false;

            // Open a connection
            using (var connection = new SqlConnection(connectionString).EnsureOpen())
            {
                var commandType = DataEntityExtension.GetCommandType <T>(command);

                // Check for the command type
                if (commandType != CommandType.StoredProcedure)
                {
                    var mappedName  = DataEntityExtension.GetMappedName <T>(command);
                    var commandText = @"
                        SELECT CONVERT(INT, c.is_identity) AS IsIdentity
                        FROM [sys].[columns] c
                        INNER JOIN [sys].[objects] o ON o.object_id = c.object_id
                        WHERE (c.[name] = @ColumnName)
	                        AND (o.[name] = @TableName)
	                        AND (o.[type] = 'U');"    ;

                    // Open a command
                    using (var dbCommand = connection.EnsureOpen().CreateCommand(commandText))
                    {
                        // Create parameters
                        dbCommand.CreateParameters(new
                        {
                            ColumnName = columnName.AsUnquoted(),
                            TableName  = mappedName.AsUnquoted()
                        });

                        // Execute and set the result
                        var result = dbCommand.ExecuteScalar();
                        if (result != null && result != DBNull.Value)
                        {
                            isIdentity = Convert.ToBoolean(result);
                        }
                    }
                }
            }

            // Return the value
            return(isIdentity);
        }
示例#20
0
        /// <summary>
        /// Creates a SQL Statement for repository <i>InlineUpdate</i> operation that is meant for SQL Server.
        /// </summary>
        /// <typeparam name="TEntity">
        /// The <i>DataEntity</i> object bound for the SQL Statement to be created.
        /// </typeparam>
        /// <param name="queryBuilder">An instance of query builder used to build the SQL statement.</param>
        /// <param name="fields">The list of the fields to be a part of inline update operation in SQL Statement composition.</param>
        /// <param name="where">The query expression for SQL statement.</param>
        /// <param name="overrideIgnore">
        /// Set to <i>true</i> if the defined <i>RepoDb.Attributes.IgnoreAttribute</i> would likely
        /// be ignored on the inline update operation in SQL Statement composition.
        /// </param>
        /// <returns>A string containing the composed SQL Statement for <i>InlineUpdate</i> operation.</returns>
        public string CreateInlineUpdate <TEntity>(QueryBuilder <TEntity> queryBuilder, IEnumerable <Field> fields,
                                                   QueryGroup where, bool?overrideIgnore = false)
            where TEntity : DataEntity
        {
            var primary   = DataEntityExtension.GetPrimaryProperty <TEntity>();
            var hasFields = fields?.Any(field => field.Name.ToLower() != primary?.GetMappedName().ToLower());

            // Check if there are fields
            if (hasFields == false)
            {
                throw new InvalidOperationException($"No inline updatable fields found at type '{typeof(TEntity).FullName}'.");
            }

            // Get the target properties
            var updateableProperties       = DataEntityExtension.GetPropertiesFor <TEntity>(Command.Update);
            var inlineUpdateableProperties = DataEntityExtension.GetPropertiesFor <TEntity>(Command.InlineUpdate)
                                             .Where(property => property != primary && updateableProperties.Contains(property))
                                             .Select(property => property.GetMappedName());

            // Check for the unmatches
            if (overrideIgnore == false)
            {
                var unmatchesProperties = fields?.Where(field =>
                                                        inlineUpdateableProperties?.FirstOrDefault(property => field.Name.ToLower() == property.ToLower()) == null);
                if (unmatchesProperties.Count() > 0)
                {
                    throw new InvalidOperationException($"The fields '{unmatchesProperties.Select(field => field.AsField()).Join(", ")}' are not " +
                                                        $"inline updateable for object '{DataEntityExtension.GetMappedName<TEntity>(Command.InlineUpdate)}'.");
                }
            }

            // Build the SQL Statement
            queryBuilder = queryBuilder ?? new QueryBuilder <TEntity>();
            queryBuilder
            .Clear()
            .Update()
            .TableFrom(Command.InlineUpdate)
            .Set()
            .FieldsAndParametersFrom(fields)
            .WhereFrom(where)
            .End();

            // Return the query
            return(queryBuilder.GetString());
        }
示例#21
0
        /// <summary>
        /// Creates a SQL Statement for repository <i>BatchQuery</i> operation that is meant for SQL Server.
        /// </summary>
        /// <typeparam name="TEntity">
        /// The <i>DataEntity</i> object bound for the SQL Statement to be created.
        /// </typeparam>
        /// <param name="queryBuilder">An instance of query builder used to build the SQL statement.</param>
        /// <param name="where">The query expression for SQL statement.</param>
        /// <param name="page">The page of the batch.</param>
        /// <param name="rowsPerBatch">The number of rows per batch.</param>
        /// <param name="orderBy">The list of fields used for ordering.</param>
        /// <returns>A string containing the composed SQL Statement for <i>BatchQuery</i> operation.</returns>
        public string CreateBatchQuery <TEntity>(QueryBuilder <TEntity> queryBuilder, QueryGroup where, int page, int rowsPerBatch, IEnumerable <OrderField> orderBy)
            where TEntity : DataEntity
        {
            var queryProperties      = DataEntityExtension.GetPropertiesFor <TEntity>(Command.Query);
            var batchQueryProperties = DataEntityExtension.GetPropertiesFor <TEntity>(Command.BatchQuery)
                                       .Where(property => queryProperties.Contains(property));
            var fields = batchQueryProperties.Select(property => new Field(property.GetMappedName()));

            // Validate the fields
            if (fields?.Any() == false)
            {
                throw new InvalidOperationException($"No batch queryable fields found from type '{typeof(TEntity).FullName}'.");
            }

            // Build the SQL Statement
            queryBuilder = queryBuilder ?? new QueryBuilder <TEntity>();
            queryBuilder
            .Clear()
            .With()
            .WriteText("CTE")
            .As()
            .OpenParen()
            .Select()
            .RowNumber()
            .Over()
            .OpenParen()
            .OrderByFrom(orderBy)
            .CloseParen()
            .As("[RowNumber],")
            .FieldsFrom(fields)
            .From()
            .TableFrom(Command.BatchQuery)
            .WhereFrom(where)
            .CloseParen()
            .Select()
            .FieldsFrom(fields)
            .From()
            .WriteText("CTE")
            .WriteText($"WHERE ([RowNumber] BETWEEN {(page * rowsPerBatch) + 1} AND {(page + 1) * rowsPerBatch})")
            .OrderByFrom(orderBy)
            .End();

            // Return the query
            return(queryBuilder.GetString());
        }
示例#22
0
        /// <summary>
        /// Creates a SQL Statement for repository <i>Update</i> operation that is meant for SQL Server.
        /// </summary>
        /// <typeparam name="TEntity">
        /// The <i>DataEntity</i> object bound for the SQL Statement to be created.
        /// </typeparam>
        /// <param name="queryBuilder">An instance of query builder used to build the SQL statement.</param>
        /// <param name="where">The query expression for SQL statement.</param>
        /// <returns>A string containing the composed SQL Statement for <i>Update</i> operation.</returns>
        public string CreateUpdate <TEntity>(QueryBuilder <TEntity> queryBuilder, QueryGroup where)
            where TEntity : DataEntity
        {
            queryBuilder = queryBuilder ?? new QueryBuilder <TEntity>();
            var fields = DataEntityExtension.GetPropertiesFor <TEntity>(Command.Update)
                         .Where(property => property != DataEntityExtension.GetPrimaryProperty <TEntity>())
                         .Select(p => new Field(p.Name));

            queryBuilder
            .Clear()
            .Update()
            .TableFrom(Command.Update)
            .Set()
            .FieldsAndParametersFrom(fields)
            .WhereFrom(where)
            .End();
            return(queryBuilder.GetString());
        }
示例#23
0
        /// <summary>
        /// Gets the cached mapped-name for the entity.
        /// </summary>
        /// <param name="entityType">The type of the data entity.</param>
        /// <returns>The cached mapped name of the entity.</returns>
        public static string Get(Type entityType)
        {
            // Validate
            ThrowNullReferenceException(entityType, "EntityType");

            // Variables
            var key    = GenerateHashCode(entityType);
            var result = (string)null;

            // Try get the value
            if (m_cache.TryGetValue(key, out result) == false)
            {
                result = DataEntityExtension.GetMappedName(entityType);
                m_cache.TryAdd(key, result);
            }

            // Return the value
            return(result);
        }
        /// <summary>
        /// Creates a new instance of <i>RepoDb.DataEntityListDataReader</i> object.
        /// </summary>
        /// <param name="entities">The list of the <i>DataEntity</i> object to be used for manipulation.</param>
        /// <param name="command">The type of command to be used by this data reader.</param>
        public DataEntityListDataReader(IEnumerable <TEntity> entities, Command command)
        {
            if (entities == null)
            {
                throw new NullReferenceException("The entities could not be null.");
            }

            // Fields
            _isClosed        = false;
            _isDisposed      = false;
            _position        = -1;
            _recordsAffected = -1;

            // Properties
            Properties = DataEntityExtension.GetPropertiesFor <TEntity>(command).ToList();
            Enumerator = entities.GetEnumerator();
            Entities   = entities;
            FieldCount = Properties.Count;
        }
示例#25
0
        /// <summary>
        /// Creates a SQL Statement for repository <i>BatchQuery</i> operation that is meant for SQL Server.
        /// </summary>
        /// <typeparam name="TEntity">
        /// The <i>DataEntity</i> object bound for the SQL Statement to be created.
        /// </typeparam>
        /// <param name="queryBuilder">An instance of query builder used to build the SQL statement.</param>
        /// <param name="where">The query expression for SQL statement.</param>
        /// <param name="page">The page of the batch.</param>
        /// <param name="rowsPerBatch">The number of rows per batch.</param>
        /// <param name="orderBy">The list of fields used for ordering.</param>
        /// <returns>A string containing the composed SQL Statement for <i>BatchQuery</i> operation.</returns>
        public string CreateBatchQuery <TEntity>(QueryBuilder <TEntity> queryBuilder, QueryGroup where, int page, int rowsPerBatch, IEnumerable <OrderField> orderBy)
            where TEntity : DataEntity
        {
            var queryProperties      = DataEntityExtension.GetPropertiesFor <TEntity>(Command.Query);
            var batchQueryProperties = DataEntityExtension.GetPropertiesFor <TEntity>(Command.BatchQuery)
                                       .Where(property => queryProperties.Contains(property));
            var fields = batchQueryProperties.Select(property => new Field(property.Name));

            // Build the SQL Statement
            queryBuilder = queryBuilder ?? new QueryBuilder <TEntity>();
            queryBuilder
            .Clear()
            .With()
            .WriteText("CTE")
            .As()
            .OpenParen()
            .Select()
            .RowNumber()
            .Over()
            .OpenParen()
            .OrderByFrom(orderBy)
            .CloseParen()
            .As("[RowNumber],")
            .FieldsFrom(Command.BatchQuery)
            .From()
            .TableFrom(Command.BatchQuery)
            .WhereFrom(where)
            .CloseParen()
            .Select()
            .FieldsFrom(fields)
            .From()
            .WriteText("CTE")
            .WriteText($"WHERE ([RowNumber] BETWEEN {(page * rowsPerBatch) + 1} AND {(page + 1) * rowsPerBatch})")
            .OrderByFrom(orderBy)
            .End();

            // Return the query
            return(queryBuilder.GetString());
        }
示例#26
0
        /// <summary>
        /// Gets the cached mapped-name for the entity.
        /// </summary>
        /// <param name="type">The type of the target entity.</param>
        /// <param name="quoted">True whether the string is quoted.</param>
        /// <param name="dbSetting">The database setting that is currently in used.</param>
        /// <returns>The cached mapped name of the entity.</returns>
        internal static string Get(Type type,
                                   bool quoted,
                                   IDbSetting dbSetting)
        {
            var key    = type.FullName.GetHashCode() + quoted.GetHashCode();
            var result = (string)null;

            // Add the DbSetting hashcode
            if (dbSetting != null)
            {
                key += dbSetting.GetHashCode();
            }

            // Try get the value
            if (m_cache.TryGetValue(key, out result) == false)
            {
                result = DataEntityExtension.GetMappedName(type, quoted, dbSetting);
                m_cache.TryAdd(key, result);
            }

            // Return the value
            return(result);
        }
示例#27
0
        /// <summary>
        /// Gets the <i>RepoDb.Attributes.MapAttribute.Name</i> value implemented on the data entity on a target command.
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="connectionString">The connection string object to be used.</param>
        /// <param name="command">The target command.</param>
        /// <returns>A boolean value indicating the identification of the column.</returns>
        public static bool Get <TEntity>(string connectionString, Command command)
            where TEntity : DataEntity
        {
            var key   = $"{typeof(TEntity).FullName}.{command.ToString()}".ToLower();
            var value = false;

            lock (_syncLock)
            {
                if (_cache.ContainsKey(key))
                {
                    value = _cache[key];
                }
                else
                {
                    var primary = DataEntityExtension.GetPrimaryProperty <TEntity>();
                    if (primary != null)
                    {
                        value = SqlDbHelper.IsIdentity <TEntity>(connectionString, command, primary.Name);
                    }
                    _cache.Add(key, value);
                }
            }
            return(value);
        }
示例#28
0
        /// <summary>
        /// Creates a SQL Statement for repository <i>Query</i> operation that is meant for SQL Server.
        /// </summary>
        /// <typeparam name="TEntity">
        /// The <i>DataEntity</i> object bound for the SQL Statement to be created.
        /// </typeparam>
        /// <param name="queryBuilder">An instance of query builder used to build the SQL statement.</param>
        /// <param name="where">The query expression for SQL statement.</param>
        /// <param name="orderBy">The list of fields  to be used for ordering in SQL Statement composition.</param>
        /// <param name="top">The number of rows to be returned by the <i>Query</i> operation in SQL Statement composition.</param>
        /// <returns>A string containing the composed SQL Statement for <i>Query</i> operation.</returns>
        public string CreateQuery <TEntity>(QueryBuilder <TEntity> queryBuilder, QueryGroup where, IEnumerable <OrderField> orderBy = null, int?top = 0)
            where TEntity : DataEntity
        {
            var properties = DataEntityExtension.GetPropertiesFor <TEntity>(Command.Query);

            if (properties?.Any() == false)
            {
                throw new InvalidOperationException($"No queryable fields found from type '{typeof(TEntity).FullName}'.");
            }
            var fields = properties?.Select(property => new Field(property.GetMappedName().AsQuoted(true)));

            queryBuilder = queryBuilder ?? new QueryBuilder <TEntity>();
            queryBuilder
            .Clear()
            .Select()
            .TopFrom(top)
            .FieldsFrom(fields)
            .From()
            .TableFrom(Command.Query)
            .WhereFrom(where)
            .OrderByFrom(orderBy)
            .End();
            return(queryBuilder.GetString());
        }
示例#29
0
        /// <summary>
        /// Gets the list of <see cref="DbField"/> of the table.
        /// </summary>
        /// <typeparam name="TDbConnection">The type of <see cref="DbConnection"/> object.</typeparam>
        /// <param name="connection">The instance of the connection object.</param>
        /// <param name="tableName">The name of the target table.</param>
        /// <param name="transaction">The transaction object that is currently in used.</param>
        /// <returns>A list of <see cref="DbField"/> of the target table.</returns>
        private string GetIdentityFieldName <TDbConnection>(TDbConnection connection,
                                                            string tableName,
                                                            IDbTransaction transaction = null)
            where TDbConnection : IDbConnection
        {
            // Sql text
            var commandText = "SELECT sql FROM [sqlite_master] WHERE name = @TableName AND type = 'table';";
            var sql         = connection.ExecuteScalar <string>(commandText, new { TableName = DataEntityExtension.GetTableName(tableName) });
            var fields      = ParseTableFieldsFromSql(sql);

            // Iterate the fields
            if (fields != null && fields.Length > 0)
            {
                foreach (var field in fields)
                {
                    if (field.ToUpper().Contains("AUTOINCREMENT"))
                    {
                        return(field.Substring(0, field.IndexOf(" ")));
                    }
                }
            }

            // Return null
            return(null);
        }
示例#30
0
 /// <summary>
 /// Returns the command text that is being used to extract schema definitions.
 /// </summary>
 /// <param name="tableName">The name of the target table.</param>
 /// <returns>The command text.</returns>
 private string GetCommandText(string tableName)
 {
     return($"pragma table_info({DataEntityExtension.GetTableName(tableName)});");
 }