예제 #1
0
        // you should use this to create inserters BUT you should cache them
        // if rules are used, column names are guessed
        // yeah use [Table] and [Column] instead
        public static FastBulkInserter <TEntity> CreateBulkInserter <TEntity>(TableMappingRules rules = null)
        {
            var guessingMode = rules != null;
            var props        = ReflectionHelper.GetProps <TEntity>();

            var    tableAttrs = typeof(TEntity).GetCustomAttributes(typeof(TableAttribute), true);
            string tableName  = null;

            if (rules != null)
            {
                tableName = rules.TableName;
            }
            else
            {
                tableName = tableAttrs.Length > 0 ? ((TableAttribute)tableAttrs[0]).Name : null;
            }
            var mappedProps = new List <MapperPropertyData>();
            var sql         = new StringBuilder();

            sql.Append("INSERT INTO ");
            sql.Append(tableName);
            sql.Append(" (");

            // yeah we build this at the same cycle

            var valuesSql = new StringBuilder();

            valuesSql.Append("VALUES (");
            int index             = 0;
            var mappedColumnNames = new List <string>(props.Length);

            foreach (var prop in props)
            {
                var columnAttr = prop.GetCustomAttributes(typeof(ColumnAttribute), true);
                // we only take first column attribute
                var columnName = columnAttr.Length > 0 ? ((ColumnAttribute)columnAttr[0]).Name : null;

                if (columnName == null && !guessingMode)
                {
                    // we skip columns with no [Column] attribute
                    continue;
                }

                var typeOk = ParameterTypeMap.TryGetValue(prop.PropertyType, out var recommendedParamType);
                if (!typeOk && prop.PropertyType.IsEnum)
                {
                    typeOk = true;
                    recommendedParamType = DbParameterTypeNumbers.Number;
                }

                if (!typeOk)
                {
                    // skip unknown parameters. TODO: log this?
                    // example of skipped types: collections, navigation props etc
                    continue;
                }
                if (guessingMode)
                {
                    columnName = rules.ColumnNameGenerator(prop);
                    // a way to skip property - return null from name generator
                    if (columnName == null)
                    {
                        continue;
                    }
                }

                var paramNameInQuery = ":B" + index.ToString();
                mappedProps.Add(new MapperPropertyData {
                    Name                 = prop.Name,
                    DbColumnName         = columnName,
                    FieldType            = prop.PropertyType,
                    ParameterNameInQuery = paramNameInQuery,
                    RecommendedDbType    = recommendedParamType
                });
                mappedColumnNames.Add(prop.Name);
                sql.Append(columnName);
                sql.Append(",");
                index++;
                valuesSql.Append(paramNameInQuery);
                valuesSql.Append(",");
            }
            ;

            // remove last ',' and close both strings
            sql.Length--;
            sql.Append(") ");
            valuesSql.Length--;
            valuesSql.Append(')');

            sql.Append(valuesSql);
            var finalSql     = sql.ToString();
            var extractor    = new FieldExtract <TEntity, object>(mappedColumnNames.ToArray());
            var bulkInserter = new FastBulkInserter <TEntity>()
            {
                InsertSql      = finalSql,
                Properties     = mappedProps,
                TableName      = tableName,
                FieldExtractor = extractor
            };

            return(bulkInserter);
        }
예제 #2
0
 public static void Add <TEntity>(FastBulkInserter <TEntity> inserter)
 {
     cache.Add(typeof(TEntity), inserter);
 }