public static void Build <TAttribute, TBuilderArg>(
            ModelBuilder modelBuilder,
            CreateBuilderArgument <TAttribute, TBuilderArg> createBuilderArgument,
            BuildModel <TBuilderArg> build
            ) where TAttribute : Attribute
        {
            var entityTypes = modelBuilder.Model.GetEntityTypes();

            Parallel.ForEach(entityTypes, entityType =>
            {
                var builderArgs = CreateBuilderArguments(entityType, createBuilderArgument);
                if (builderArgs.Length == 0)
                {
                    return;
                }

                Action <TBuilderArg> buildModel = BuildAction <TBuilderArg>(modelBuilder, entityType, build);

                lock (modelBuilder)
                {
                    foreach (var arg in builderArgs)
                    {
                        buildModel(arg);
                    }
                }
            });
        }
        private static TBuilderArg[] CreateBuilderArguments <TBuilderArg, TAttribute>(
            IMutableEntityType entityType,
            CreateBuilderArgument <TAttribute, TBuilderArg> createBuilderArgument
            )
            where TAttribute : Attribute
        {
            var annotatedProperties = entityType.ClrType
                                      .GetProperties()
                                      .SelectMany(prop => Attribute.GetCustomAttributes(prop, typeof(TAttribute))
                                                  .Cast <TAttribute>()
                                                  .Select(attrib => new AnnotatedProperty <TAttribute>(prop.Name, attrib))
                                                  ).ToArray();

            return(createBuilderArgument(annotatedProperties));
        }