public static void UseWorkspace(this MetadataModelBuilder builder, MetadataWorkspace metadata)
        {
            var entityTypes = metadata
                              .GetItems <EntityType>(DataSpace.CSpace);

            foreach (var entity in entityTypes)
            {
                var entityBuilder = builder.FromEntityType(metadata, entity);
            }
        }
        public static void UseDbModel(this MetadataModelBuilder builder, IModel model)
        {
            var entities = model.GetEntityTypes().ToList();

            entities = entities.Where(p => p.FindPrimaryKey() != null).ToList();

            foreach (var entity in entities)
            {
                var entityBuilder = builder.FromEntityType(entity);
            }
        }
        private static EntityMetadataBuilder FromEntityType(this MetadataModelBuilder builder, MetadataWorkspace metadata, EntityType entityType)
        {
            var objectItemCollection = (ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace);
            var mapping = metadata.GetItems <EntityContainerMapping>(DataSpace.CSSpace)
                          .Single()
                          .EntitySetMappings
                          .SelectMany(p => p.EntityTypeMappings);

            var objectTypes = metadata.GetItems <EntityType>(DataSpace.OSpace);

            var objectType = objectTypes.Single(p => p.Name == entityType.Name);
            var clrType    = objectItemCollection.GetClrType(objectType);

            var entityBuilder = builder.Entity(clrType);

            if (entityType.BaseType != null)
            {
                var baseEntityBuilder = builder.FromEntityType(metadata, (EntityType)entityType.BaseType);
                entityBuilder.BaseEntity = baseEntityBuilder;
            }

            var propertyMappings = mapping.SelectMany(p => p.Fragments.SelectMany(x => x.PropertyMappings)).OfType <ScalarPropertyMapping>().ToList();

            var joined = from p in entityType.Properties.Where(p => p.DeclaringType == entityType)
                         join m in propertyMappings on p equals m.Property
                         select new { Property = p, Column = m.Column };

            foreach (var prop in joined)
            {
                var propertyClrType = metadata.GetClrTypeFromCSpaceType(prop.Property);

                var propBuilder = entityBuilder.Property(prop.Property.Name, propertyClrType);
                propBuilder.Nullable = prop.Property.Nullable;
                if (prop.Column.IsStoreGeneratedComputed)
                {
                    propBuilder.ValueGeneration = AutoGenerateValue.Both;
                }
                else if (prop.Column.IsStoreGeneratedIdentity)
                {
                    propBuilder.ValueGeneration = AutoGenerateValue.OnInsert;
                }

                propBuilder.HasDefaultValue = prop.Column.MetadataProperties.Any(p => p.IsAnnotation && p.Name.EndsWith(":" + DefaultValueAnnotation.AnnotationName, StringComparison.Ordinal));

                if (propBuilder is TextPropertyBuilder textBuilder)
                {
                    textBuilder.MaxLength = prop.Property.MaxLength;
                }
                else if (propBuilder is BlobPropertyBuilder blobPropertyBuilder)
                {
                    blobPropertyBuilder.MaxLength = prop.Property.MaxLength;
                }
            }

            if (entityType.BaseType == null)
            {
                foreach (var pk in entityType.KeyProperties)
                {
                    entityBuilder.PrimaryKey.Add(pk.Name);
                }
            }

            foreach (var nav in entityType.NavigationProperties.Where(p => p.DeclaringType == entityType))
            {
                NavigationPropertyBuilder navBuilder = null;

                ////var navpropMatch = from l in item.EntityMetadata.Properties.OfType<NavigationPropertyMetadata>()
                ////                   join r in item.EntityType.NavigationProperties on l.Name equals r.Name
                ////                   select new { Left = l, Right = r };

                ////foreach (var npmatch in navpropMatch)
                ////{
                ////    var test = entityTypes.SelectMany(p => p.NavigationProperties)
                ////                          .FirstOrDefault(p => p.ToEndMember == npmatch.Right.FromEndMember);

                var inverse = nav.ToEndMember.GetEntityType().NavigationProperties.FirstOrDefault(p => p.FromEndMember == nav.ToEndMember);

                ////var inverse = nav.ToEndMember.MetadataProperties.FirstOrDefault(p => p.Name == "ClrPropertyInfo")?.Value as PropertyInfo;

                var targetObjectType = objectTypes.Single(p => p.Name == nav.ToEndMember.GetEntityType().Name);
                var targetClrType    = objectItemCollection.GetClrType(targetObjectType);

                string        targetPropertyName = inverse?.Name;
                List <string> foreignKeys        = new List <string>();

                var multiplicity       = GetMultiplicity(nav.ToEndMember.RelationshipMultiplicity);
                var targetMultiplicity = GetMultiplicity(nav.FromEndMember.RelationshipMultiplicity);

                if (multiplicity != NavigationPropertyMultiplicity.Many)
                {
                    foreignKeys.AddRange(nav.GetDependentProperties().Select(p => p.Name));
                }

                navBuilder = entityBuilder.Navigation(nav.Name);

                navBuilder.Nullable           = multiplicity == NavigationPropertyMultiplicity.ZeroOrOne;
                navBuilder.Multiplicity       = multiplicity;
                navBuilder.Target             = new ClrTypeInfo(targetClrType);
                navBuilder.TargetProperty     = targetPropertyName;
                navBuilder.TargetMultiplicity = targetMultiplicity;
                navBuilder.ForeignKey         = foreignKeys;
            }

            return(entityBuilder);
        }
        private static EntityMetadataBuilder FromEntityType(this MetadataModelBuilder builder, IEntityType entityType)
        {
            var entityBuilder = builder.Entity(entityType.ClrType);

            if (entityType.BaseType != null)
            {
                var baseEntityBuilder = builder.FromEntityType(entityType.BaseType);
                entityBuilder.BaseEntity = baseEntityBuilder;
            }

            var properties = entityType.GetProperties().Where(p => p.DeclaringEntityType == entityType);

            foreach (var prop in properties)
            {
                var propBuilder = entityBuilder.Property(prop.Name, prop.ClrType);
                propBuilder.Nullable = prop.IsNullable;
                if (prop.ValueGenerated == ValueGenerated.OnAdd)
                {
                    propBuilder.ValueGeneration = AutoGenerateValue.OnInsert;
                }
                else if (prop.ValueGenerated == ValueGenerated.OnAddOrUpdate)
                {
                    propBuilder.ValueGeneration = AutoGenerateValue.Both;
                }
#if NETSTANDARD2_0
                else if (prop.ValueGenerated == ValueGenerated.OnUpdate)
                {
                    propBuilder.ValueGeneration = AutoGenerateValue.Both;
                }
#endif

                if (propBuilder is TextPropertyBuilder textBuilder)
                {
                    textBuilder.MaxLength = prop.GetMaxLength();
                }
                else if (propBuilder is BlobPropertyBuilder blobPropertyBuilder)
                {
                    blobPropertyBuilder.MaxLength = prop.GetMaxLength();
                }
            }

            if (entityType.BaseType == null)
            {
                foreach (var pk in entityType.FindPrimaryKey().Properties)
                {
                    entityBuilder.PrimaryKey.Add(pk.Name);
                }
            }

            foreach (var nav in entityType.GetNavigations().Where(p => p.DeclaringEntityType == entityType))
            {
                NavigationPropertyBuilder navBuilder = null;
                var           inverse            = nav.FindInverse();
                Type          targetType         = nav.GetTargetType().ClrType;
                string        targetPropertyName = inverse?.Name;
                List <string> foreignKeys        = new List <string>();

                NavigationPropertyMultiplicity multiplicity       = NavigationPropertyMultiplicity.One;
                NavigationPropertyMultiplicity targetMultiplicity = NavigationPropertyMultiplicity.One;
                if (nav.IsCollection())
                {
                    multiplicity       = NavigationPropertyMultiplicity.Many;
                    targetMultiplicity = nav.ForeignKey.IsRequired ? NavigationPropertyMultiplicity.One : NavigationPropertyMultiplicity.ZeroOrOne;
                }
                else if (nav.IsDependentToPrincipal())
                {
                    multiplicity       = nav.ForeignKey.IsRequired ? NavigationPropertyMultiplicity.One : NavigationPropertyMultiplicity.ZeroOrOne;
                    targetMultiplicity = nav.ForeignKey.IsUnique ? NavigationPropertyMultiplicity.ZeroOrOne : NavigationPropertyMultiplicity.Many;

                    foreignKeys = nav.ForeignKey.Properties.Select(p => p.Name).ToList();
                }
                else
                {
                    multiplicity       = NavigationPropertyMultiplicity.ZeroOrOne;
                    targetMultiplicity = NavigationPropertyMultiplicity.One;
                }

                navBuilder = entityBuilder.Navigation(nav.Name);

                navBuilder.Nullable           = multiplicity == NavigationPropertyMultiplicity.ZeroOrOne;
                navBuilder.Multiplicity       = multiplicity;
                navBuilder.Target             = new ClrTypeInfo(targetType);
                navBuilder.TargetProperty     = targetPropertyName;
                navBuilder.TargetMultiplicity = targetMultiplicity;
                navBuilder.ForeignKey         = foreignKeys;
            }

            return(entityBuilder);
        }