internal static void GenerateProperty(IEdmProperty property, TypeBuilder typeBuilder, ModuleBuilder moduleBuilder, int?keyIndex = null)
        {
            var propertyName = property.Name;
            var emdPropType  = property.Type.PrimitiveKind();
            var propertyType = GetPrimitiveClrType(emdPropType, false);

            if (propertyType == null)
            {
                if (property.Type.FullName().ToLower().Contains("geography"))
                {
                    return;
                }

                if (property.PropertyKind == EdmPropertyKind.Navigation)
                {
                    if (property.Type.FullName().StartsWith("Collection"))
                    {
                        var  typeName = collectionRegex.Match(property.Type.FullName()).Groups[1].Value;
                        Type listOf   = typeof(List <>);
                        var  baseType = _typeBuildersDict.ContainsKey(typeName) ? _typeBuildersDict[typeName].Builder : typeof(string);

                        var selfContained = listOf.MakeGenericType(baseType);
                        propertyType = selfContained;
                    }
                    else
                    {
                        var navProptype = _typeBuildersDict[property.Type.FullName()];
                        propertyType = navProptype.Builder;
                    }
                }
                else
                {
                    if (property.Type.FullName().StartsWith("Collection"))
                    {
                        var  typeName      = collectionRegex.Match(property.Type.FullName()).Groups[1].Value;
                        Type listOf        = typeof(List <>);
                        var  baseType      = _typeBuildersDict.ContainsKey(typeName) ? _typeBuildersDict[typeName].Builder : typeof(string);
                        var  selfContained = listOf.MakeGenericType(baseType);
                        propertyType = selfContained;
                    }
                    else
                    {
                        var previouslyBuiltType = _typeBuildersDict[property.Type.FullName()];

                        propertyType = previouslyBuiltType.Builder;
                    }
                }
            }

            if (property.Type.IsNullable && propertyType.IsValueType)
            {
                Type nullableOf    = typeof(Nullable <>);
                Type selfContained = nullableOf.MakeGenericType(propertyType);
                propertyType = selfContained;
            }

            PropertyBuilderHelper.BuildProperty(typeBuilder, propertyName, propertyType, keyIndex);
        }
        public static void BuildModules(IEdmModel model, ModuleBuilder moduleBuilder, string dbContextName)
        {
            //first create the basic types for the enums
            foreach (var modelSchemaElement in model.SchemaElements)
            {
                var declaredType = model.FindDeclaredType(modelSchemaElement.FullName());
                if (declaredType == null)
                {
                    continue;
                }
                if (declaredType is IEdmEnumType)
                {
                    CreateType((IEdmEnumType)declaredType, moduleBuilder, declaredType.FullName());
                }
            }

            //next create the basic types for the types
            foreach (var modelSchemaElement in model.SchemaElements)
            {
                var declaredType = model.FindDeclaredType(modelSchemaElement.FullName());
                if (declaredType == null)
                {
                    continue;
                }
                if (!(declaredType is IEdmEnumType))
                {
                    CreateType((IEdmStructuredType)declaredType, moduleBuilder, declaredType.FullName());
                }
                else
                {
                    Compile((IEdmEnumType)declaredType, moduleBuilder, declaredType.FullName());
                }
            }

            //go through and add all elements and their properties but not nav properties
            foreach (var modelSchemaElement in model.SchemaElements)
            {
                var one = model.FindDeclaredType(modelSchemaElement.FullName());
                if (one != null && !(modelSchemaElement is IEdmEnumType))
                {
                    Compile((IEdmStructuredType)one, moduleBuilder, one.FullName());
                }
            }

            //finally add the nav properties
            foreach (var modelSchemaElement in model.SchemaElements)
            {
                if ((modelSchemaElement is IEdmEnumType))
                {
                    continue;
                }
                var one = model.FindDeclaredType(modelSchemaElement.FullName());
                if (one != null)
                {
                    Compile((IEdmStructuredType)one, moduleBuilder, one.FullName(), true);
                }
            }

            //now go through the queue and create the types in dependency order
            while (_builderQueue.Count != 0)
            {
                var typeBuilder = _builderQueue.Dequeue();
                if ((object)typeBuilder.Builder is TypeBuilder)
                {
                    ((TypeBuilder)(object)typeBuilder.Builder).CreateTypeInfo();
                }
                if ((object)typeBuilder.Builder is EnumBuilder)
                {
                    ((EnumBuilder)(object)typeBuilder.Builder).CreateTypeInfo();
                }
            }


            //generate the DbContext type
            // TODO: this created an EfCore DbContext
            //var entitiesBuilder = moduleBuilder.DefineType(dbContextName, TypeAttributes.Class | TypeAttributes.Public, typeof(DbContext));
            //var dbContextType = typeof(DbContext);
            ////entitiesBuilder.CreateDefaultConstructor(dbContextType, $"name={dbContextName}");
            ////entitiesBuilder.CreateConnectionStringConstructor(dbContextType);
            //entitiesBuilder.CreateContextOptionsConstructor(dbContextType);

            var entitiesBuilder = moduleBuilder.DefineType(dbContextName, TypeAttributes.Class | TypeAttributes.Public, typeof(ListDataStore));
            var dbContextType   = typeof(ListDataStore);

            foreach (var entitySet in model.EntityContainer.EntitySets())
            {
                TypeBuilderInfo entityType = _typeBuildersDict.FirstOrDefault(t => t.Key == entitySet.EntityType().FullName()).Value;
                if (entityType != null)
                {
                    //Type listOf = typeof(DbSet<>);
                    Type listOf        = typeof(ListDataSet <>);
                    Type selfContained = listOf.MakeGenericType(entityType.Builder);
                    PropertyBuilderHelper.BuildProperty(entitiesBuilder, entitySet.Name, selfContained);
                }
            }

//            // create the OnModelCreating method
//            MethodBuilder methodbuilder = entitiesBuilder.DefineMethod("OnModelCreating", MethodAttributes.Public
//                                                                                          | MethodAttributes.HideBySig
//                                                                                          | MethodAttributes.CheckAccessOnOverride
//                                                                                          | MethodAttributes.Virtual,
//                                                                                          typeof(void), new Type[] { typeof(DbModelBuilder) });

//            // generate the IL for the OnModelCreating method
//            ILGenerator ilGenerator = methodbuilder.GetILGenerator();
////todo: insert code
//            ilGenerator.Emit(OpCodes.Ret);
            entitiesBuilder.CreateType();
        }