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); }
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); } }
/// <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; }