protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            if (targetModel != null)
            {
                foreach (EntityModel item in targetModel.Entities)
                {
                    Type dynamicEntityType = DynamicEntityTypeManager.CreateTypeFromEntityDefinition(targetModel, item, DateTime.UtcNow);

                    MethodInfo registerMethod = modelBuilder.GetType().GetMethod("Entity").MakeGenericMethod(dynamicEntityType);
                    dynamic    configuration  = registerMethod.Invoke(modelBuilder, null);
                    // configuration.MapInheritedProperties();
                    var action = new Action <dynamic>(m =>
                    {
                        m.MapInheritedProperties();
                        m.ToTable(item.Name);
                    });
                    configuration.Map(action);
                    //DataStructures.Attribute primaryKey = item.Attributes.First(a => a.AttributeInfo.IsPrimaryKey == true);
                    //configuration.HasKey(primaryKey

                    /*modelBuilder.Entity<BaseEntity>().Map(m =>
                     * {
                     *  m.MapInheritedProperties();
                     *  m.ToTable(item.Name);
                     * });*/
                    ///.HasKey<string>(ent => ent.Name);
                }
            }

            DbModel model = null;

            if (targetModel.Databases.Count > 0 && !string.IsNullOrEmpty(this.cnnString))
            {
                if (targetModel.Databases[0].Connector.Contains("MSSQL"))
                {
                    var providerFactory = System.Data.Common.DbProviderFactories.GetFactory("System.Data.SqlClient");
                    System.Data.Common.DbConnection connection = providerFactory.CreateConnection();
                    connection.ConnectionString = this.cnnString;
                    model = modelBuilder.Build(connection);
                }
            }
            else
            {
                var provider = new DbProviderInfo("System.Data.SqlClient", "2008");
                model = modelBuilder.Build(provider);
            }

            string edmxpath = System.IO.Path.Combine(targetModel.ParentProject.Path, System.IO.Path.ChangeExtension(targetModel.Path, "edmx"));

            if (System.IO.File.Exists(edmxpath))
            {
                System.IO.File.Delete(edmxpath);
            }
            var writer = new XmlTextWriter(edmxpath, Encoding.ASCII);

            EdmxWriter.WriteEdmx(model, writer);
            writer.Flush();
            writer.Close();
            //base.OnModelCreating(modelBuilder);
        }
Exemple #2
0
        /// <summary>
        /// Create a new dynamic entity strongly typed class base on a xsd document
        /// </summary>
        /// <param name="entityDefinition">Entity Definition to be parsed</param>
        /// <param name="timestamp">timestamp of the last version of the XSD definition</param>
        /// <returns>return the dynamic entity generate type base on the xsd.</returns>
        public static Type CreateTypeFromEntityDefinition(DatabaseModel ParentModel, EntityModel entityDefinition, DateTime timestamp)
        {
            lock (currentTypes)
            {
                string entityName = entityDefinition.Name;
                //System.Xml.Schema.XmlSchemaSet x;
                //x = new System.Xml.Schema.XmlSchemaSet();
                entityName = entityName.Replace(".", "_");
                Type currentType = DynamicEntityTypeManager.GetType(entityName);
                if (currentType == null)
                {
                    if (moduleBuilder == null)
                    {
                        InitData(ParentModel);
                    }

                    TypeBuilder typeBuilder = GetTypeBuilder(entityName);

                    Type[]             constructorArgTypes     = new Type[] { };
                    ConstructorBuilder constructorBuilder      = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, constructorArgTypes);
                    Type[]             baseConstructorArgTypes = new Type[] { typeof(string) };
                    ILGenerator        ilGenerator             = constructorBuilder.GetILGenerator();
                    ConstructorInfo    baseConstructor         = typeof(DynamicEntityBase).GetConstructor(baseConstructorArgTypes);
                    ilGenerator.Emit(OpCodes.Ldarg_0);
                    ilGenerator.Emit(OpCodes.Ldstr, entityDefinition.Name);
                    ilGenerator.Emit(OpCodes.Call, baseConstructor);
                    ilGenerator.Emit(OpCodes.Ret);

                    // add copy constructor

                    /* constructorArgTypes = new Type[] { typeof(DynamicEntityBase) };
                     * ConstructorBuilder constructorBuilder2 = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, constructorArgTypes);
                     * Type[] baseConstructorArgTypes2 = new Type[] { typeof(DynamicEntityBase) };
                     * ConstructorInfo baseConstructor2 = typeof(DynamicEntityBase).GetConstructor(baseConstructorArgTypes2);
                     * ilGenerator = constructorBuilder2.GetILGenerator();
                     * ilGenerator.Emit(OpCodes.Ldarg_0);
                     * ilGenerator.Emit(OpCodes.Ldarg_1);
                     * ilGenerator.Emit(OpCodes.Call, baseConstructor2);
                     * ilGenerator.Emit(OpCodes.Nop);
                     * ilGenerator.Emit(OpCodes.Nop);
                     * ilGenerator.Emit(OpCodes.Nop);
                     * ilGenerator.Emit(OpCodes.Ret);*/

                    foreach (EntityAttributeModel element in entityDefinition.Attributes)
                    {
                        string propName = element.Name;
                        if (propertNameRegex.IsMatch(propName, 0))
                        {
                            // gets the type code of the property, and ensure that they don't have the namespace to basic schema definition
                            Type propType = DynamicEntityTypeManager.GetClrTypeFromPropertyType(element.AttributeType);

                            CreateProperty(typeBuilder, propName, propType, element.AttributeInfo.IsPrimaryKey, element.AttributeInfo.IsPrimaryKey, null);
                        }
                        else
                        {
                            throw new ArgumentException(
                                      @"Each property name must be 
                            alphanumeric and start with character.");
                        }
                    }

                    // temporary type info for forward reference
                    currentTypes[entityName] = new DynamicTypeInfo(entityName, timestamp, typeBuilder);

                    foreach (EntityRelationshipModel relationship in entityDefinition.Relationships)
                    {
                        string propName = relationship.Name;
                        if (propertNameRegex.IsMatch(propName, 0))
                        {
                            // gets the type code of the property, and ensure that they don't have the namespace to basic schema definition
                            Type        relationshipType       = DynamicEntityTypeManager.GetType(relationship.TargetTableName);
                            EntityModel targetEntityDefinition = ParentModel.Entities.FirstOrDefault(entity => entity.Name == relationship.TargetTableName);
                            bool        isBuildChild           = false;
                            if (relationshipType == null)
                            {
                                if (relationship.TargetTableName == entityDefinition.Name)
                                {
                                    // reference this same type being build
                                    relationshipType = typeBuilder;
                                    isBuildChild     = false;
                                }
                                else
                                {
                                    // create the type look for the model entity definition
                                    relationshipType = CreateTypeFromEntityDefinition(ParentModel, targetEntityDefinition, DateTime.UtcNow);
                                    isBuildChild     = true;
                                }
                            }

                            Type propType = null;
                            List <CustomAttributeBuilder> additionalAttributes = new List <CustomAttributeBuilder>();
                            if (relationship.SupportMultipleRelationships)
                            {
                                propType = typeof(ICollection <>).MakeGenericType(relationshipType);
                                if (!string.IsNullOrEmpty(relationship.InverseRelationshipName))
                                {
                                    EntityRelationshipModel inverseRelation      = targetEntityDefinition.Relationships.FirstOrDefault(rel => rel.Name == relationship.InverseRelationshipName);
                                    ConstructorInfo         attributeConstructor = null;
                                    CustomAttributeBuilder  attributeBuilder     = null;
                                    if (inverseRelation != null)
                                    {
                                        attributeConstructor = typeof(System.ComponentModel.DataAnnotations.Schema.InversePropertyAttribute).GetConstructor(new Type[] { typeof(string) });
                                        attributeBuilder     = new CustomAttributeBuilder(attributeConstructor, new object[] { relationship.InverseRelationshipName }, new FieldInfo[] { }, new object[] { });
                                        additionalAttributes.Add(attributeBuilder);
                                    }
                                }
                            }
                            else
                            {
                                propType = relationshipType;
                                if (!string.IsNullOrEmpty(relationship.InverseRelationshipName))
                                {
                                    EntityRelationshipModel inverseRelation      = targetEntityDefinition.Relationships.FirstOrDefault(rel => rel.Name == relationship.InverseRelationshipName);
                                    ConstructorInfo         attributeConstructor = null;
                                    CustomAttributeBuilder  attributeBuilder     = null;
                                    if (inverseRelation != null)
                                    {
                                        attributeConstructor = typeof(System.ComponentModel.DataAnnotations.Schema.InversePropertyAttribute).GetConstructor(new Type[] { typeof(string) });
                                        attributeBuilder     = new CustomAttributeBuilder(attributeConstructor, new object[] { relationship.InverseRelationshipName }, new FieldInfo[] { }, new object[] { });
                                        additionalAttributes.Add(attributeBuilder);
                                    }

                                    //create foreign key field
                                    EntityAttributeModel targetKey = targetEntityDefinition.Attributes.FirstOrDefault(a => a.AttributeInfo.IsPrimaryKey);
                                    if (targetKey != null)
                                    {
                                        string fkFieldName = relationship.Name + "_FK";
                                        attributeConstructor = typeof(System.ComponentModel.DataAnnotations.Schema.ForeignKeyAttribute).GetConstructor(new Type[] { typeof(string) });
                                        if (inverseRelation.SupportMultipleRelationships)
                                        {
                                            CreateProperty(typeBuilder, fkFieldName, DynamicEntityTypeManager.GetClrTypeFromPropertyType(targetKey.AttributeType), false, true, null);
                                            attributeBuilder = new CustomAttributeBuilder(attributeConstructor, new object[] { fkFieldName }, new FieldInfo[] { }, new object[] { });
                                        }
                                        else
                                        {
                                            attributeBuilder = new CustomAttributeBuilder(attributeConstructor, new object[] { targetKey.Name }, new FieldInfo[] { }, new object[] { });
                                        }
                                        additionalAttributes.Add(attributeBuilder);
                                    }
                                }
                            }

                            if (propType == null)
                            {
                                throw new NullReferenceException(string.Format("The relationship {0} type can't be determinate", relationship.Name));
                            }

                            CreateProperty(typeBuilder, propName, propType, false, !isBuildChild, additionalAttributes);
                        }
                        else
                        {
                            throw new ArgumentException(
                                      @"Each property name must be 
                            alphanumeric and start with character.");
                        }
                    }

                    Type newType = typeBuilder.CreateType();

                    //currentTypes[resourceFriendlyName] = newType;
                    currentTypes[entityName] = new DynamicTypeInfo(entityName, timestamp, newType);

                    //assemblyBuilder.Save("BLTypeManagerTest.dll");

                    return(newType);
                }
                return(currentType);
            }
        }