A simple fix/improvement would be to replace the StringDictionary metaData in in the base Shape class with a reference to the System.Data.IDataRecord derived from the DbDataReader in the ShapeFile class.
The Shape.GetMetadata() and Shape.GetMetadatanames() methods would be replaced with a System.Data.IDataRecord "Attributes" property.
This would provide a performance improvement because all the attributes would not need to be unnecessarily parsed and converted to String with every read of the Enumerator,
Also, The code accessing the Shape descendant would have access to the underlying type metadata AND ordinal, typed access to the underlying values. Another performance gain.