Esempio n. 1
0
        private void DoBulkInsert(DbContext dbContext, object parent, string childPropertyName, IEnumerable <object> objectsToInsert)
        {
            Type   entityClrType = objectsToInsert.First().GetType();
            string entityName    = entityClrType.Name;

            //Debug.Print(entityName);

            PropertyInfo entityKeyPropertyInfo = GetEntityKeyPropertyInfo(entityClrType);

            SqlCeCommand cmd = connection.CreateCommand();

            cmd.CommandType = System.Data.CommandType.TableDirect;
            cmd.CommandText = GetTableName(entityName);

            SqlCeResultSet rs = cmd.ExecuteResultSet(ResultSetOptions.Updatable | ResultSetOptions.Scrollable);

            // Scalar Properties
            // AuotIncrement Property
            PropertyInfo auotIncrementPropInfo            = null;
            Dictionary <PropertyInfo, int> ordinalMapping = null;

            if (scalarMappingCache.ContainsKey(entityName))
            {
                ordinalMapping        = scalarMappingCache[entityName].Item1;
                auotIncrementPropInfo = scalarMappingCache[entityName].Item2;
            }
            else
            {
                Dictionary <string, string> scalarMappingDictionary = edmx.GetScalarPropertiesMappingDictionary(entityName);
                Dictionary <string, string> revisedColumnMapping    = RemoveAutoIncrementColumns(GetTableName(entityName), scalarMappingDictionary);
                ordinalMapping = GetAttributeToColumnOrdinalMapping(dbContext, entityClrType, rs, revisedColumnMapping);

                string auotIncrementPropertyName = scalarMappingDictionary.Keys.Except(revisedColumnMapping.Keys).SingleOrDefault();
                if (!string.IsNullOrEmpty(auotIncrementPropertyName))
                {
                    auotIncrementPropInfo = entityClrType.GetProperty(auotIncrementPropertyName);
                }

                scalarMappingCache.Add(entityName, Tuple.Create(ordinalMapping, auotIncrementPropInfo));
            }

            // Navigation Properties, Lookups
            if (!ordinalLookupMappingCache.ContainsKey(entityClrType))
            {
                ordinalLookupMappingCache.Add(entityClrType,
                                              GetAttributeToColumnOrdinalMapping(dbContext, entityClrType, rs, edmx.GetLookupPropertiesMappingDictionary(entityClrType)));
            }
            Dictionary <PropertyInfo, int> ordinalLookupMapping = ordinalLookupMappingCache[entityClrType];

            // Navigation Properties, Lists
            if (!listPropertiesCache.ContainsKey(entityClrType))
            {
                listPropertiesCache.Add(entityClrType, edmx.GetListProperties(entityClrType));
            }
            List <NavigationProperty> listNavigationProperties = listPropertiesCache[entityClrType];

            // Parent
            PropertyInfo parentKeyPropertyInfo = null;
            int          parentColumnOrdinal   = 0;

            if (parent != null)
            {
                Type   parentType       = parent.GetType();
                string parentEntityName = parentType.Name;
                string columnName       = string.Empty;

                if (parentChildRelationCache.ContainsKey(Tuple.Create(parentEntityName, childPropertyName)))
                {
                    parentKeyPropertyInfo = parentChildRelationCache[Tuple.Create(parentEntityName, childPropertyName)].Item1;
                    columnName            = parentChildRelationCache[Tuple.Create(parentEntityName, childPropertyName)].Item2;
                }
                else
                {
                    EndProperty endProperty = edmx.GetParentChildRelationEndProperty(parentEntityName, childPropertyName);
                    columnName = endProperty.ScalarProperties.Single().ColumnName;
                    string parentEntityKeyPropertyName = edmx.GetEntityKeyPropertyName(parentEntityName);
                    parentKeyPropertyInfo = parentType.GetProperty(parentEntityKeyPropertyName);
                    parentChildRelationCache.Add(Tuple.Create(parentEntityName, childPropertyName), Tuple.Create(parentKeyPropertyInfo, columnName));
                }

                SqlCeUpdatableRecord recParent = rs.CreateRecord();
                parentColumnOrdinal = recParent.GetOrdinal(columnName);
            }

            foreach (var element in objectsToInsert)
            {
                if (IsObjectAlreadyInserted(element, entityKeyPropertyInfo))
                {
                    continue;
                }

                SqlCeUpdatableRecord rec = rs.CreateRecord();

                // Scalar Properties
                foreach (var ordinalMappingEntry in ordinalMapping)
                {
                    object value = ordinalMappingEntry.Key.GetValue(element, null);
                    rec.SetValue(ordinalMappingEntry.Value, value);
                }

                // Navigation Properties, Lookups
                foreach (var ordinalLookupMappingEntry in ordinalLookupMapping)
                {
                    object lookupInstance = ordinalLookupMappingEntry.Key.GetValue(element, null);
                    if (lookupInstance != null)
                    {
                        DoBulkInsert(dbContext, null, string.Empty, new object[] { lookupInstance });

                        Type   lookupType         = ordinalLookupMappingEntry.Key.PropertyType;
                        string lookupPropertyName = ordinalLookupMappingEntry.Key.Name;
                        var    dictKeyTuple       = Tuple.Create(entityName, lookupPropertyName);
                        if (!lookupMappingCache.ContainsKey(dictKeyTuple))
                        {
                            string lookupKeyPropertyName = edmx.GetEntityKeyPropertyName(lookupType.Name);
                            lookupMappingCache.Add(dictKeyTuple,
                                                   Tuple.Create(ordinalLookupMappingEntry.Value, lookupType.GetProperty(lookupKeyPropertyName)));
                        }

                        int    lookupOrdinal = lookupMappingCache[dictKeyTuple].Item1;
                        object value         = lookupMappingCache[dictKeyTuple].Item2.GetValue(lookupInstance, null);

                        rec.SetValue(lookupOrdinal, value);
                    }
                }

                if (parent != null)
                {
                    rec.SetValue(parentColumnOrdinal, parentKeyPropertyInfo.GetValue(parent, null));
                }

                rs.Insert(rec);

                if (auotIncrementPropInfo != null)
                {
                    auotIncrementPropInfo.SetValue(element, int.Parse(commandIdentity.ExecuteScalar().ToString()), null);
                }

                // Navigation Properties, Lists
                foreach (NavigationProperty navigationProperty in listNavigationProperties)
                {
                    object value = entityClrType.GetProperty(navigationProperty.Name).GetValue(element, null);
                    if (value != null && value is ICollection)
                    {
                        IEnumerable <object> childList = (IEnumerable <object>)value;
                        if (childList.Count() > 0)
                        {
                            DoBulkInsert(dbContext, element, navigationProperty.Name, childList);
                        }
                    }
                }
            }
        }