public void TestSqlConnectionExecuteQueryFromQueryBuilderCreateQueryForNotInOperationViaArray() { // Setup var tables = Helper.CreateIdentityTables(10); var values = new long[] { 1, 3, 4, 8 }; var where = new QueryGroup(new QueryField("Id", Operation.NotIn, values)); var fields = FieldCache.Get <IdentityTable>(); using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb)) { // Act connection.InsertAll(tables); // Setup var builder = connection.GetStatementBuilder(); var sql = builder.CreateQuery(null, ClassMappedNameCache.Get <IdentityTable>(), fields: fields, where : where); // Act var result = connection.ExecuteQuery <IdentityTable>(sql, where); // Assert Assert.AreEqual(6, result.Count()); result.AsList().ForEach(item => { Assert.IsFalse(values.Contains(item.Id)); Helper.AssertPropertiesEquality(tables.First(v => v.Id == item.Id), item); }); } }
public void TestSqlConnectionExecuteNonQueryFromQueryBuilderCreateBatchQuery() { // Setup var tables = Helper.CreateIdentityTables(10); var where = new QueryGroup(new QueryField("Id", Operation.GreaterThanOrEqual, 0)); var fields = FieldCache.Get <IdentityTable>(); using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb)) { // Act connection.InsertAll(tables); // Setup var builder = connection.GetStatementBuilder(); var sql = builder.CreateBatchQuery(null, ClassMappedNameCache.Get <IdentityTable>(), fields: fields, page: 2, rowsPerBatch: 2, orderBy: OrderField.Ascending <IdentityTable>(e => e.Id).AsEnumerable(), where : where); // Act var result = connection.ExecuteQuery <IdentityTable>(sql, where); // Assert Assert.AreEqual(2, result.Count()); result.AsList().ForEach(item => { Helper.AssertPropertiesEquality(tables.First(v => v.Id == item.Id), item); }); } }
public void TestSqlConnectionExecuteNonQueryFromQueryBuilderCreateInsert() { // Setup var table = Helper.CreateIdentityTables(1).First(); var fields = FieldCache.Get <IdentityTable>(); using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb)) { // Setup var dbFields = DbFieldCache.Get(connection, ClassMappedNameCache.Get <IdentityTable>(), null); var builder = connection.GetStatementBuilder(); var sql = builder.CreateInsert(null, ClassMappedNameCache.Get <IdentityTable>(), fields: fields, primaryField: dbFields.FirstOrDefault(e => e.IsPrimary), identityField: dbFields.FirstOrDefault(e => e.IsIdentity)); // Act var id = connection.ExecuteScalar(sql, table); // Assert Assert.IsNotNull(id); // Setup var result = connection.QueryAll <IdentityTable>().First(); // Assert Helper.AssertPropertiesEquality(table, result); } }
public void TestSqlConnectionExecuteNonQueryFromQueryBuilderCreateQueryAll() { // Setup var tables = Helper.CreateIdentityTables(10); var fields = FieldCache.Get <IdentityTable>(); using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb)) { // Act connection.InsertAll(tables); // Setup var builder = connection.GetStatementBuilder(); var sql = builder.CreateQueryAll(null, ClassMappedNameCache.Get <IdentityTable>(), fields: fields); // Act var result = connection.ExecuteQuery <IdentityTable>(sql); // Assert Assert.AreEqual(tables.Count(), result.Count()); result.AsList().ForEach(item => { Helper.AssertPropertiesEquality(tables.First(v => v.Id == item.Id), item); }); } }
public void ThrowExceptionOnSqlConnectionExecuteQueryFromQueryBuilderCreateQueryForNotBetweenOperationViaListWithMoreVaues() { // Setup var tables = Helper.CreateIdentityTables(10); var values = new List <long> { 1, 3, 7 }; var where = new QueryGroup(new QueryField("Id", Operation.NotBetween, values)); var fields = FieldCache.Get <IdentityTable>(); using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb)) { // Act connection.InsertAll(tables); // Setup var builder = connection.GetStatementBuilder(); var sql = builder.CreateQuery(null, ClassMappedNameCache.Get <IdentityTable>(), fields: fields, where : where); // Act connection.ExecuteQuery <IdentityTable>(sql, where); } }
public void TestFieldCacheGetForDerivedClass() { // Act var fields = FieldCache.Get <DerivedClass>().AsList(); // Assert Assert.AreEqual(4, fields.Count()); }
/// <summary> /// /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="connection"></param> /// <param name="dbFields"></param> /// <param name="tableName"></param> /// <param name="fields"></param> /// <param name="commandText"></param> /// <returns></returns> private static InsertExecutionContext <TEntity> CreateInternal <TEntity>(IDbConnection connection, IEnumerable <DbField> dbFields, string tableName, IEnumerable <Field> fields, string commandText) where TEntity : class { var typeOfEntity = typeof(TEntity); var dbSetting = connection.GetDbSetting(); var identity = (Field)null; var inputFields = (IEnumerable <DbField>)null; var identityDbField = dbFields?.FirstOrDefault(f => f.IsIdentity); // Set the identity field if (typeOfEntity.IsClassType()) { identity = IdentityCache.Get <TEntity>()?.AsField() ?? FieldCache .Get <TEntity>()? .FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), identityDbField?.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) ?? identityDbField?.AsField(); } // Filter the actual properties for input fields inputFields = dbFields? .Where(dbField => dbField.IsIdentity == false) .Where(dbField => fields.FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), dbField.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) != null) .AsList(); // Variables for the entity action var identityPropertySetter = (Action <TEntity, object>)null; // Get the identity setter if (typeOfEntity.IsClassType() == true && identity != null) { identityPropertySetter = FunctionCache.GetDataEntityPropertySetterCompiledFunction <TEntity>(identity); } // Return the value return(new InsertExecutionContext <TEntity> { CommandText = commandText, InputFields = inputFields, ParametersSetterFunc = FunctionCache.GetDataEntityDbParameterSetterCompiledFunction <TEntity>( string.Concat(typeof(TEntity).FullName, StringConstant.Period, tableName, ".Insert"), inputFields?.AsList(), null, dbSetting), IdentityPropertySetterFunc = identityPropertySetter }); }
/// <summary> /// /// </summary> /// <param name="entityType"></param> /// <param name="connection"></param> /// <param name="dbFields"></param> /// <param name="tableName"></param> /// <param name="fields"></param> /// <param name="commandText"></param> /// <returns></returns> private static MergeExecutionContext CreateInternal(Type entityType, IDbConnection connection, IEnumerable <DbField> dbFields, string tableName, IEnumerable <Field> fields, string commandText) { var dbSetting = connection.GetDbSetting(); var identity = (Field)null; var inputFields = new List <DbField>(); var identityDbField = dbFields?.FirstOrDefault(f => f.IsIdentity); // Set the identity field identity = IdentityCache.Get(entityType)?.AsField() ?? FieldCache .Get(entityType)? .FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), identityDbField?.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) ?? identityDbField?.AsField(); // Filter the actual properties for input fields inputFields = dbFields? .Where(dbField => fields.FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), dbField.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) != null) .AsList(); // Variables for the entity action var identityPropertySetter = (Action <object, object>)null; // Get the identity setter if (identity != null) { identityPropertySetter = FunctionCache.GetDataEntityPropertySetterCompiledFunction(entityType, identity); } // Return the value return(new MergeExecutionContext { CommandText = commandText, InputFields = inputFields, ParametersSetterFunc = FunctionCache.GetDataEntityDbParameterSetterCompiledFunction(entityType, string.Concat(entityType.FullName, StringConstant.Period, tableName, ".Merge"), inputFields?.AsList(), null, dbSetting), IdentityPropertySetterFunc = identityPropertySetter }); }
public void TestFieldCacheGet() { // Act var properties = typeof(DerivedClass).GetProperties().AsList(); var fields = FieldCache.Get <DerivedClass>().AsList(); // Assert Assert.AreEqual(4, properties.Count()); Assert.AreEqual(4, fields.Count()); properties.ForEach(p => { var field = fields.FirstOrDefault(f => f.Name == p.Name); Assert.IsNotNull(field); Assert.AreEqual(p.PropertyType, field.Type); }); }
public void TestSqlConnectionExecuteNonQueryFromQueryBuilderCreateUpdate() { // Setup var table = Helper.CreateIdentityTables(1).First(); var fields = FieldCache.Get <IdentityTable>(); using (var connection = new SqlConnection(Database.ConnectionStringForRepoDb)) { // Act var id = connection.Insert(table); // Set the properties table.ColumnNVarChar = $"{table.ColumnNVarChar}-Updated"; // Setup var where = new QueryGroup(new QueryField("Id", id)); // Setup var dbFields = DbFieldCache.Get(connection, ClassMappedNameCache.Get <IdentityTable>(), null); var builder = connection.GetStatementBuilder(); var sql = builder.CreateUpdate(null, ClassMappedNameCache.Get <IdentityTable>(), fields: fields, where : where, primaryField: dbFields.FirstOrDefault(e => e.IsPrimary), identityField: dbFields.FirstOrDefault(e => e.IsIdentity)); // Act var affectedRow = connection.ExecuteNonQuery(sql, table); // Assert Assert.AreEqual(1, affectedRow); // Setup var result = connection.QueryAll <IdentityTable>().First(); // Assert Helper.AssertPropertiesEquality(table, result); } }
public void TestSQLiteConnectionInsertAsyncForIdentityReusability() { using (var connection = new SQLiteConnection(Database.ConnectionStringSDS)) { // Create the tables Database.CreateSdsTables(connection); // Setup var tables = Helper.CreateSdsCompleteTables(10).AsList(); // Act var insertAllResult = connection.InsertAll <SdsCompleteTable>(tables); // Assert Assert.AreEqual(tables.Count, insertAllResult); Assert.AreEqual(tables.Count, connection.CountAll <SdsCompleteTable>()); // Setup (3) var deleteEntity = tables[2]; // Act (3) var deleteResult = connection.Delete <SdsCompleteTable>(deleteEntity); // Assert Assert.AreEqual(1, deleteResult); Assert.AreEqual(tables.Count - 1, connection.CountAll <SdsCompleteTable>()); // Setup var table = Helper.CreateSdsCompleteTables(1).First(); // Act (3) var fields = FieldCache.Get <SdsCompleteTable>().Where(e => e.Name != "Id"); var insertResult = connection.InsertAsync <SdsCompleteTable>(table, fields: fields).Result; // Assert (3) Assert.AreEqual(deleteEntity.Id, insertResult); } }
/// <summary> /// Map the Selection name values from the specified Selection Names provided to the /// RepoDb specific values that have the underlying DB field name (as potentially mapped on the Model). /// All Fields are returned as a default if the value is undefined and/or invalid and cannot be mapped. /// NOTE: Property names and db fields names are not guaranteed to be the same. /// </summary> /// <param name="selectionNamesFilter"></param> /// <returns> /// List of Database fields mapped from all of the available GraphQL Selections mapped to the generics /// model type TEntity specified. As a fallback default, all DB Fields are returned if no Selections are available from the /// GraphQL ParamsContext. /// </returns> public IEnumerable <Field> GetSelectFields(IEnumerable <string> selectionNamesFilter) { // Ensure we are null safe and Get all the fields in that case... if (selectionNamesFilter == null) { //NOTE: Since there's no need to filter we can just get ALL fields from the FieldCache! return(FieldCache.Get <TModel>()); } else { //NOTE: For GraphQL we need to lookup the actual Db field by the Model's Property Name // and then convert to the actual DB field name; which might also be mapped name via RepoDb attribute. // For more info see: https://repodb.net/cacher/propertymappednamecache //TODO: Add Caching Layer here if needed to Cached a Reverse Dictionary of mappings by Model Name! var mappingLookup = PropertyCache.Get <TModel>().ToLookup(p => p.PropertyInfo.Name.ToLower()); var selectFields = selectionNamesFilter .Select(name => mappingLookup[name.ToLower()]?.FirstOrDefault()?.AsField()) .Where(prop => prop != null); return(selectFields); } }
/// <summary> /// Base DbConnection (SqlConnection) extension for Relay Cursor Paginated Batch Query capability. /// /// Public Facade method to provide dynamically paginated results using Relay Cursor slicing. /// Relay spec cursor algorithm is implemented for Sql Server on top of RepoDb. /// /// NOTE: Since RepoDb supports only Offset Batch querying, this logic provided as an extension /// of RepoDb core functionality; and if this is ever provided by the Core functionality /// this facade will remain as a proxy to core feature. /// /// NOTE: For Relay Spec details and Cursor Algorithm see: /// https://relay.dev/graphql/connections.htm#sec-Pagination-algorithm /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="dbConnection">Extends DbConnection directly</param> /// <param name="orderBy"></param> /// <param name="where">May be either a QueryGroup or RawSqlWhere object</param> /// <param name="pagingParams"></param> /// <param name="tableName"></param> /// <param name="hints"></param> /// <param name="fields"></param> /// <param name="commandTimeout"></param> /// <param name="transaction"></param> /// <param name="logTrace"></param> /// <param name="cancellationToken"></param> /// <returns>CursorPageSlice<TEntity></returns> internal static async Task <CursorPageSlice <TEntity> > GraphQLBatchSliceQueryInternalAsync <TEntity>( this DbConnection dbConnection, IEnumerable <OrderField> orderBy, object where = null, //NOTE: May be either a QueryGroup or RawSqlWhere object IRepoDbCursorPagingParams pagingParams = default, string tableName = null, string hints = null, IEnumerable <Field> fields = null, int?commandTimeout = null, IDbTransaction transaction = null, Action <string> logTrace = null, CancellationToken cancellationToken = default ) //ALL entities retrieved and Mapped for Cursor Pagination must support IHaveCursor interface. where TEntity : class { if (orderBy == null) { throw new ArgumentNullException(nameof(orderBy), "A sort order must be specified to provide valid cursor paging results."); } var dbTableName = string.IsNullOrWhiteSpace(tableName) ? ClassMappedNameCache.Get <TEntity>() : tableName; //Ensure we have default fields; default is to include All Fields... var fieldsList = fields?.ToList(); var selectFields = fieldsList?.Any() == true ? fieldsList : FieldCache.Get <TEntity>(); //Retrieve only the select fields that are valid for the Database query! //NOTE: We guard against duplicate values as a convenience. var validSelectFields = await dbConnection .GetValidatedDbFieldsAsync(dbTableName, selectFields.Distinct()) .ConfigureAwait(false); //Dynamically handle RepoDb where filters (QueryGroup or now supporting Raw Sql and Params object)... var validatedWhereParams = where switch { QueryGroup whereQueryGroup => RepoDbQueryGroupProxy.GetMappedParamsObject <TEntity>(whereQueryGroup), RawSqlWhere whereRawSql => whereRawSql.WhereParams, _ => null }; //Build the Cursor Paging query... var querySliceInfo = RepoDbBatchSliceQueryBuilder.BuildSqlServerBatchSliceQuery <TEntity>( tableName: dbTableName, fields: validSelectFields, orderBy: orderBy, where : where, hints: hints, afterCursorIndex: pagingParams?.AfterIndex, firstTake: pagingParams?.First, beforeCursorIndex: pagingParams?.BeforeIndex, lastTake: pagingParams?.Last, //Optionally we compute the Total Count only when requested! includeTotalCountQuery: pagingParams?.IsTotalCountRequested ?? false ); //Now we can execute the process and get the results! var cursorPageResult = await dbConnection.ExecuteBatchSliceQueryAsync <TEntity>( sqlQuerySliceInfo : querySliceInfo, queryParams : validatedWhereParams, tableName : dbTableName, commandTimeout : commandTimeout, transaction : transaction, logTrace : logTrace, cancellationToken : cancellationToken ).ConfigureAwait(false); return(cursorPageResult); }
/// <summary> /// /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="connection"></param> /// <param name="tableName"></param> /// <param name="dbFields"></param> /// <param name="batchSize"></param> /// <param name="fields"></param> /// <param name="commandText"></param> /// <returns></returns> private static InsertAllExecutionContext <TEntity> CreateInternal <TEntity>(IDbConnection connection, string tableName, IEnumerable <DbField> dbFields, int batchSize, IEnumerable <Field> fields, string commandText) where TEntity : class { var typeOfEntity = typeof(TEntity); var dbSetting = connection.GetDbSetting(); var identity = (Field)null; var inputFields = (IEnumerable <DbField>)null; var identityDbField = dbFields?.FirstOrDefault(f => f.IsIdentity); // Set the identity value if (typeOfEntity.IsClassType()) { identity = IdentityCache.Get <TEntity>()?.AsField() ?? FieldCache .Get <TEntity>()? .FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), identityDbField?.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) ?? identityDbField?.AsField(); } // Filter the actual properties for input fields inputFields = dbFields? .Where(dbField => dbField.IsIdentity == false) .Where(dbField => fields.FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), dbField.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) != null) .AsList(); // Variables for the context var multipleEntitiesFunc = (Action <DbCommand, IList <TEntity> >)null; var identitySettersFunc = (List <Action <TEntity, DbCommand> >)null; var singleEntityFunc = (Action <DbCommand, TEntity>)null; var identitySetterFunc = (Action <TEntity, object>)null; // Get if we have not skipped it if (typeOfEntity.IsClassType() && identity != null) { identitySetterFunc = FunctionCache.GetDataEntityPropertySetterCompiledFunction <TEntity>(identity); } // Identity which objects to set if (batchSize <= 1) { singleEntityFunc = FunctionCache.GetDataEntityDbParameterSetterCompiledFunction <TEntity>( string.Concat(typeof(TEntity).FullName, StringConstant.Period, tableName, ".InsertAll"), inputFields?.AsList(), null, dbSetting); } else { multipleEntitiesFunc = FunctionCache.GetDataEntityListDbParameterSetterCompiledFunction <TEntity>( string.Concat(typeof(TEntity).FullName, StringConstant.Period, tableName, ".InsertAll"), inputFields?.AsList(), null, batchSize, dbSetting); } // Return the value return(new InsertAllExecutionContext <TEntity> { CommandText = commandText, InputFields = inputFields, BatchSize = batchSize, SingleDataEntityParametersSetterFunc = singleEntityFunc, MultipleDataEntitiesParametersSetterFunc = multipleEntitiesFunc, IdentityPropertySetterFunc = identitySetterFunc, IdentityPropertySettersFunc = identitySettersFunc }); }
/// <summary> /// Converts an instance of an object into an enumerable list of field. /// </summary> /// <typeparam name="TEntity">The target type.</typeparam> /// <param name="entity">The instance to be converted.</param> /// <returns>An enumerable list of fields.</returns> internal static IEnumerable <Field> AsFields <TEntity>(this TEntity entity) where TEntity : class => FieldCache.Get <TEntity>();
/// <summary> /// /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="connection"></param> /// <param name="dbFields"></param> /// <param name="tableName"></param> /// <param name="fields"></param> /// <param name="hints"></param> /// <param name="transaction"></param> /// <param name="statementBuilder"></param> /// <param name="skipIdentityCheck"></param> /// <returns></returns> private static InsertExecutionContext <TEntity> CreateInternal <TEntity>(IDbConnection connection, IEnumerable <DbField> dbFields, string tableName, IEnumerable <Field> fields, string hints = null, IDbTransaction transaction = null, IStatementBuilder statementBuilder = null, bool skipIdentityCheck = false) where TEntity : class { var dbSetting = connection.GetDbSetting(); var identity = (Field)null; var inputFields = (IEnumerable <DbField>)null; var identityDbField = dbFields?.FirstOrDefault(f => f.IsIdentity); // Set the identity field if (skipIdentityCheck == false) { identity = IdentityCache.Get <TEntity>()?.AsField(); if (identity == null && identityDbField != null) { identity = FieldCache.Get <TEntity>().FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), identityDbField.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)); } } // Filter the actual properties for input fields inputFields = dbFields? .Where(dbField => dbField.IsIdentity == false) .Where(dbField => fields.FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), dbField.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) != null) .AsList(); // Variables for the entity action var identityPropertySetter = (Action <TEntity, object>)null; // Get the identity setter if (skipIdentityCheck == false && identity != null) { identityPropertySetter = FunctionCache.GetDataEntityPropertySetterCompiledFunction <TEntity>(identity); } // Identify the requests var insertRequest = new InsertRequest(tableName, connection, transaction, fields, hints, statementBuilder); // Return the value return(new InsertExecutionContext <TEntity> { CommandText = CommandTextCache.GetInsertText(insertRequest), InputFields = inputFields, ParametersSetterFunc = FunctionCache.GetDataEntityDbParameterSetterCompiledFunction <TEntity>( string.Concat(typeof(TEntity).FullName, StringConstant.Period, tableName, ".Insert"), inputFields?.AsList(), null, dbSetting), IdentityPropertySetterFunc = identityPropertySetter }); }
/// <summary> /// /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="connection"></param> /// <param name="tableName"></param> /// <param name="dbFields"></param> /// <param name="batchSize"></param> /// <param name="fields"></param> /// <param name="hints"></param> /// <param name="transaction"></param> /// <param name="statementBuilder"></param> /// <param name="skipIdentityCheck"></param> /// <returns></returns> private static InsertAllExecutionContext <TEntity> CreateInternal <TEntity>(IDbConnection connection, string tableName, IEnumerable <DbField> dbFields, int batchSize, IEnumerable <Field> fields, string hints = null, IDbTransaction transaction = null, IStatementBuilder statementBuilder = null, bool skipIdentityCheck = false) where TEntity : class { var dbSetting = connection.GetDbSetting(); var identity = (Field)null; var inputFields = (IEnumerable <DbField>)null; var identityDbField = dbFields?.FirstOrDefault(f => f.IsIdentity); // Set the identity value if (skipIdentityCheck == false) { identity = IdentityCache.Get <TEntity>()?.AsField(); if (identity == null && identityDbField != null) { identity = FieldCache.Get <TEntity>().FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), identityDbField.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)); } } // Filter the actual properties for input fields inputFields = dbFields? .Where(dbField => dbField.IsIdentity == false) .Where(dbField => fields.FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), dbField.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) != null) .AsList(); // Variables for the context var multipleEntitiesFunc = (Action <DbCommand, IList <TEntity> >)null; var identitySettersFunc = (List <Action <TEntity, DbCommand> >)null; var singleEntityFunc = (Action <DbCommand, TEntity>)null; var identitySetterFunc = (Action <TEntity, object>)null; // Get if we have not skipped it if (skipIdentityCheck == false && identity != null) { identitySetterFunc = FunctionCache.GetDataEntityPropertySetterCompiledFunction <TEntity>(identity); } // Identity which objects to set if (batchSize <= 1) { singleEntityFunc = FunctionCache.GetDataEntityDbParameterSetterCompiledFunction <TEntity>( string.Concat(typeof(TEntity).FullName, StringConstant.Period, tableName, ".InsertAll"), inputFields?.AsList(), null, dbSetting); } else { multipleEntitiesFunc = FunctionCache.GetDataEntityListDbParameterSetterCompiledFunction <TEntity>( string.Concat(typeof(TEntity).FullName, StringConstant.Period, tableName, ".InsertAll"), inputFields?.AsList(), null, batchSize, dbSetting); } // Identify the requests var insertAllRequest = (InsertAllRequest)null; var insertRequest = (InsertRequest)null; // Create a different kind of requests if (batchSize > 1) { insertAllRequest = new InsertAllRequest(tableName, connection, transaction, fields, batchSize, hints, statementBuilder); } else { insertRequest = new InsertRequest(tableName, connection, transaction, fields, hints, statementBuilder); } // Return the value return(new InsertAllExecutionContext <TEntity> { CommandText = batchSize > 1 ? CommandTextCache.GetInsertAllText(insertAllRequest) : CommandTextCache.GetInsertText(insertRequest), InputFields = inputFields, BatchSize = batchSize, SingleDataEntityParametersSetterFunc = singleEntityFunc, MultipleDataEntitiesParametersSetterFunc = multipleEntitiesFunc, IdentityPropertySetterFunc = identitySetterFunc, IdentityPropertySettersFunc = identitySettersFunc }); }
/// <summary> /// /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="connection"></param> /// <param name="entities"></param> /// <param name="dbFields"></param> /// <param name="tableName"></param> /// <param name="qualifiers"></param> /// <param name="batchSize"></param> /// <param name="fields"></param> /// <param name="hints"></param> /// <param name="transaction"></param> /// <param name="statementBuilder"></param> /// <returns></returns> private static MergeAllExecutionContext <TEntity> CreateInternal <TEntity>(IDbConnection connection, IEnumerable <TEntity> entities, IEnumerable <DbField> dbFields, string tableName, IEnumerable <Field> qualifiers, int batchSize, IEnumerable <Field> fields, string hints = null, IDbTransaction transaction = null, IStatementBuilder statementBuilder = null) where TEntity : class { var typeOfEntity = typeof(TEntity); var dbSetting = connection.GetDbSetting(); var identity = (Field)null; var inputFields = (IEnumerable <DbField>)null; var identityDbField = dbFields?.FirstOrDefault(f => f.IsIdentity); // Check the fields if (fields?.Any() != true) { fields = dbFields?.AsFields(); } // Check the qualifiers if (qualifiers?.Any() != true) { var primary = dbFields?.FirstOrDefault(dbField => dbField.IsPrimary == true); qualifiers = primary?.AsField().AsEnumerable(); } // Set the identity field if (typeOfEntity.IsClassType()) { identity = IdentityCache.Get <TEntity>()?.AsField() ?? FieldCache .Get <TEntity>()? .FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), identityDbField?.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) ?? identityDbField?.AsField(); } // Filter the actual properties for input fields inputFields = dbFields? .Where(dbField => fields.FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), dbField.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) != null) .AsList(); // Exclude the fields not on the actual entity if (typeof(TEntity).IsClassType() == false) { var entityFields = Field.Parse(entities?.FirstOrDefault()); inputFields = inputFields? .Where(field => entityFields.FirstOrDefault(f => string.Equals(f.Name.AsUnquoted(true, dbSetting), field.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) != null) .AsList(); } // Variables for the context var multipleEntitiesFunc = (Action <DbCommand, IList <TEntity> >)null; var singleEntityFunc = (Action <DbCommand, TEntity>)null; var identitySetterFunc = (Action <TEntity, object>)null; // Get if we have not skipped it if (typeOfEntity.IsClassType() == true && identity != null) { identitySetterFunc = FunctionCache.GetDataEntityPropertySetterCompiledFunction <TEntity>(identity); } // Identity which objects to set if (batchSize <= 1) { singleEntityFunc = FunctionCache.GetDataEntityDbParameterSetterCompiledFunction <TEntity>( string.Concat(typeof(TEntity).FullName, StringConstant.Period, tableName, ".MergeAll"), inputFields?.AsList(), null, dbSetting); } else { multipleEntitiesFunc = FunctionCache.GetDataEntityListDbParameterSetterCompiledFunction <TEntity>( string.Concat(typeof(TEntity).FullName, StringConstant.Period, tableName, ".MergeAll"), inputFields?.AsList(), null, batchSize, dbSetting); } // Identify the requests var mergeAllRequest = (MergeAllRequest)null; var mergeRequest = (MergeRequest)null; // Create a different kind of requests if (batchSize > 1) { mergeAllRequest = new MergeAllRequest(tableName, connection, transaction, fields, qualifiers, batchSize, hints, statementBuilder); } else { mergeRequest = new MergeRequest(tableName, connection, transaction, fields, qualifiers, hints, statementBuilder); } // Return the value return(new MergeAllExecutionContext <TEntity> { CommandText = batchSize > 1 ? CommandTextCache.GetMergeAllText(mergeAllRequest) : CommandTextCache.GetMergeText(mergeRequest), InputFields = inputFields, BatchSize = batchSize, SingleDataEntityParametersSetterFunc = singleEntityFunc, MultipleDataEntitiesParametersSetterFunc = multipleEntitiesFunc, IdentityPropertySetterFunc = identitySetterFunc }); }
/// <summary> /// Converts an instance of an object into an enumerable list of field. /// </summary> /// <typeparam name="TEntity">The target type.</typeparam> /// <param name="entity">The instance to be converted.</param> /// <param name="dbSetting">The database setting that is currently in used.</param> /// <returns>An enumerable list of fields.</returns> internal static IEnumerable <Field> AsFields <TEntity>(this TEntity entity, IDbSetting dbSetting) where TEntity : class { return(FieldCache.Get <TEntity>(dbSetting)); }
/// <summary> /// /// </summary> /// <param name="entityType"></param> /// <param name="connection"></param> /// <param name="entities"></param> /// <param name="dbFields"></param> /// <param name="tableName"></param> /// <param name="qualifiers"></param> /// <param name="batchSize"></param> /// <param name="fields"></param> /// <param name="commandText"></param> /// <returns></returns> private static MergeAllExecutionContext CreateInternal(Type entityType, IDbConnection connection, IEnumerable <object> entities, IEnumerable <DbField> dbFields, string tableName, IEnumerable <Field> qualifiers, int batchSize, IEnumerable <Field> fields, string commandText) { var dbSetting = connection.GetDbSetting(); var identity = (Field)null; var inputFields = (IEnumerable <DbField>)null; var identityDbField = dbFields?.FirstOrDefault(f => f.IsIdentity); // Check the fields if (fields?.Any() != true) { fields = dbFields?.AsFields(); } // Check the qualifiers if (qualifiers?.Any() != true) { var primary = dbFields?.FirstOrDefault(dbField => dbField.IsPrimary == true); qualifiers = primary?.AsField().AsEnumerable(); } // Set the identity field identity = IdentityCache.Get(entityType)?.AsField() ?? FieldCache .Get(entityType)? .FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), identityDbField?.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) ?? identityDbField?.AsField(); // Filter the actual properties for input fields inputFields = dbFields? .Where(dbField => fields.FirstOrDefault(field => string.Equals(field.Name.AsUnquoted(true, dbSetting), dbField.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) != null) .AsList(); // Exclude the fields not on the actual entity if (entityType.IsClassType() == false) { var entityFields = Field.Parse(entities?.FirstOrDefault()); inputFields = inputFields? .Where(field => entityFields.FirstOrDefault(f => string.Equals(f.Name.AsUnquoted(true, dbSetting), field.Name.AsUnquoted(true, dbSetting), StringComparison.OrdinalIgnoreCase)) != null) .AsList(); } // Variables for the context var multipleEntitiesFunc = (Action <DbCommand, IList <object> >)null; var singleEntityFunc = (Action <DbCommand, object>)null; var identitySetterFunc = (Action <object, object>)null; // Get if we have not skipped it if (identity != null) { identitySetterFunc = FunctionCache.GetDataEntityPropertySetterCompiledFunction(entityType, identity); } // Identity which objects to set if (batchSize <= 1) { singleEntityFunc = FunctionCache.GetDataEntityDbParameterSetterCompiledFunction(entityType, string.Concat(entityType.FullName, StringConstant.Period, tableName, ".MergeAll"), inputFields, null, dbSetting); } else { multipleEntitiesFunc = FunctionCache.GetDataEntityListDbParameterSetterCompiledFunction(entityType, string.Concat(entityType.FullName, StringConstant.Period, tableName, ".MergeAll"), inputFields, null, batchSize, dbSetting); } // Return the value return(new MergeAllExecutionContext { CommandText = commandText, InputFields = inputFields, BatchSize = batchSize, SingleDataEntityParametersSetterFunc = singleEntityFunc, MultipleDataEntitiesParametersSetterFunc = multipleEntitiesFunc, IdentityPropertySetterFunc = identitySetterFunc }); }