private PropertyInfo GetReferenceEntityIdProperty(Type type, IEfBulkInsertProvider provider)
        {
            PropertyInfo property;

            if (!ReferenceEntityIdProps.TryGetValue(type, out property))
            {
                var tableMapping = provider.Context.Db(type);
                var propertyName = tableMapping.Pks.FirstOrDefault().PropertyName;

                property = type.GetProperty(propertyName);
                ReferenceEntityIdProps[type] = property;
            }

            return(property);
        }
예제 #2
0
        public static async Task BulkInsertBufferedBody <T>(IEfBulkInsertProvider bulkInsert, IEnumerable <T> entities, BulkInsertOptions options, object mutualExclusionLock)
        {
            while (true)
            {
                var buffer = new List <T>();
                lock (mutualExclusionLock)
                {
                    foreach (var item in entities)
                    {
                        buffer.Add(item);
                        if (buffer.Count == options.BatchSize)
                        {
                            break;
                        }
                    }
                }

                if (!buffer.Any())
                {
                    return;
                }
                await BulkInsertAsync(bulkInsert.Context, buffer, options);
            }
        }
예제 #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="enumerable"></param>
        /// <param name="provider"></param>
        public MappedDataReader(IEnumerable <T> enumerable, IEfBulkInsertProvider provider)
        {
            Refs = new Dictionary <Type, List <object> >();

            Provider = provider;

            var baseType = typeof(T);
            var allTypes = baseType.GetDerivedTypes(true);

            //var tableMappings = allTypes.ToDictionary(x => x, Provider.Context.Db);
            var tableMappings = new Dictionary <Type, IEntityMap>();

            foreach (var type in allTypes)
            {
                try
                {
                    var tableMapping = Provider.Context.Db(type);
                    tableMappings[type] = tableMapping;
                }
                catch
                {
                    // todo - catch only EntityTypeNotFoundException when mapping api is upgraded
                    // Maybe these derived types are not used. Throw when invalid type is used while reading.
                }
            }

            if (tableMappings.Count == 0)
            {
                throw new Exception("No table mappings provided.");
            }

            var baseMapping    = tableMappings.First().Value;
            var firstTableName = baseMapping.TableName;

            if (tableMappings.Any(x => x.Value.TableName != firstTableName))
            {
                throw new Exception("All mappings must have same table name.");
            }

            TableName  = firstTableName;
            SchemaName = baseMapping.Schema;

            Indexes   = new Dictionary <string, int>();
            Cols      = new Dictionary <int, IPropertyMap>();
            Selectors = new Dictionary <Type, Dictionary <int, Func <T, object> > >();

            enumerator = enumerable.GetEnumerator();

            int i = 0;

            foreach (var kvp in tableMappings)
            {
                var entityType = kvp.Key;
                Selectors[entityType] = new Dictionary <int, Func <T, object> >();

                var tableMapping = kvp.Value;

                var propertyMaps = tableMapping.Properties
                                   .Where(x => !x.Computed && (!x.IsNavigationProperty || x.IsFk));

                foreach (var col in propertyMaps)
                {
                    var currentIndex = i;

                    if (Indexes.ContainsKey(col.ColumnName))
                    {
                        currentIndex = Indexes[col.ColumnName];
                    }
                    else
                    {
                        Cols[currentIndex]      = col;
                        Indexes[col.ColumnName] = currentIndex;
                        ++i;
                    }

                    if (col.IsDiscriminator)
                    {
                        var x = Expression.Parameter(baseType, "x");

                        var expression = Expression.Lambda <Func <T, object> >(Expression.Convert(Expression.Constant(col.DefaultValue), typeof(object)), x);
                        var selector   = expression.Compile();
                        Selectors[entityType][currentIndex] = selector;
                    }
                    else
                    {
                        var x = Expression.Parameter(baseType, "x");

                        var        propNames          = col.PropertyName.Split('.');
                        Expression propertyExpression = baseType == entityType
                            ? Expression.PropertyOrField(x, propNames[0])
                            : Expression.PropertyOrField(Expression.Convert(x, entityType), propNames[0]);

                        propertyExpression = propNames.Skip(1).Aggregate(propertyExpression, Expression.PropertyOrField);

                        var expression = Expression.Lambda <Func <T, object> >(Expression.Convert(propertyExpression, typeof(object)), x);
                        var selector   = expression.Compile();
                        Selectors[entityType][currentIndex] = selector;
                    }
                }
            }

            FieldCount = i;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="enumerable"></param>
        /// <param name="provider"></param>
        public MappedDataReader(IEnumerable <T> enumerable, IEfBulkInsertProvider provider)
        {
            this.Refs = new Dictionary <Type, List <object> >();

            this.Provider = provider;

            var baseType = typeof(T);
            var allTypes = baseType.GetDerivedTypes(true);

            Dictionary <Type, IEntityMap> tableMappings = null;

            tableMappings = this.CreateTableMappings(allTypes);

            if (tableMappings == null || tableMappings.Count == 0)
            {
                throw new Exception($"No table mappings provided. Type {typeof(T)}.");
            }

            var baseMapping    = tableMappings.First().Value;
            var firstTableName = baseMapping.TableName;

            if (tableMappings.Any(x => x.Value.TableName != firstTableName))
            {
                throw new Exception("All mappings must have same table name. Type {typeof(T)}.");
            }

            this.TableName  = firstTableName;
            this.SchemaName = baseMapping.Schema;

            this.Indexes   = new Dictionary <string, int>();
            this.Cols      = new Dictionary <int, IPropertyMap>();
            this.Selectors = new Dictionary <Type, Dictionary <int, Func <T, object> > >();

            this._enumerator = enumerable.GetEnumerator();

            int i = 0;

            foreach (var kvp in tableMappings)
            {
                var entityType = kvp.Key;
                this.Selectors[entityType] = new Dictionary <int, Func <T, object> >();

                var tableMapping = kvp.Value;

                var propertyMaps = tableMapping.Properties
                                   .Where(x => !x.Computed && (!x.IsNavigationProperty || x.IsFk));

                foreach (var col in propertyMaps)
                {
                    var currentIndex = i;

                    if (this.Indexes.ContainsKey(col.ColumnName))
                    {
                        currentIndex = this.Indexes[col.ColumnName];
                    }
                    else
                    {
                        this.Cols[currentIndex]      = col;
                        this.Indexes[col.ColumnName] = currentIndex;
                        ++i;
                    }

                    if (col.IsDiscriminator)
                    {
                        var x = Expression.Parameter(baseType, "x");

                        var expression = Expression.Lambda <Func <T, object> >(Expression.Convert(Expression.Constant(col.DefaultValue), typeof(object)), x);
                        var selector   = expression.Compile();
                        this.Selectors[entityType][currentIndex] = selector;
                    }
                    else
                    {
                        var x = Expression.Parameter(baseType, "x");

                        var        propNames          = col.PropertyName.Split('.');
                        Expression propertyExpression = baseType == entityType
                            ? Expression.PropertyOrField(x, propNames[0])
                            : Expression.PropertyOrField(Expression.Convert(x, entityType), propNames[0]);

                        propertyExpression = propNames.Skip(1).Aggregate(propertyExpression, Expression.PropertyOrField);

                        var expression = Expression.Lambda <Func <T, object> >(Expression.Convert(propertyExpression, typeof(object)), x);
                        var selector   = expression.Compile();
                        this.Selectors[entityType][currentIndex] = selector;
                    }
                }
            }

            this.FieldCount = i;
        }