public virtual IModel CreateModel()
        {
            // the relationalModel is an IModel, but not the one that will be returned
            // it's just directly from the database - EntityType = table, Property = column
            // etc with no attempt to hook up foreign key columns or make the
            // names fit CSharp conventions etc.
            var relationalModel = ConstructRelationalModel();

            var nameMapper = new SqlServerNameMapper(
                relationalModel,
                entity => _tables[entity.Name].TableName,
                property => _tableColumns[property.Name].ColumnName);

            return ConstructCodeGenModel(relationalModel, nameMapper);
        }
        public virtual IModel ConstructCodeGenModel(
            [NotNull] IModel relationalModel, [NotNull] SqlServerNameMapper nameMapper)
        {
            Check.NotNull(relationalModel, nameof(relationalModel));
            Check.NotNull(nameMapper, nameof(nameMapper));

            var codeGenModel = new Microsoft.Data.Entity.Metadata.Model();
            foreach (var relationalEntityType in relationalModel.EntityTypes.Cast<EntityType>())
            {
                var codeGenEntityType = codeGenModel
                    .AddEntityType(nameMapper.EntityTypeToClassNameMap[relationalEntityType]);
                _relationalEntityTypeToCodeGenEntityTypeMap[relationalEntityType] = codeGenEntityType;
                codeGenEntityType.Relational().Table = _tables[relationalEntityType.Name].TableName;
                codeGenEntityType.Relational().Schema = _tables[relationalEntityType.Name].SchemaName;

                // Loop over relational properties constructing a matching property in the 
                // codeGenModel. Also accumulate:
                //    a) primary key properties
                //    b) constraint properties
                var primaryKeyProperties = new List<Property>();
                var constraints = new Dictionary<string, List<Property>>();
                _relationalEntityTypeToForeignKeyConstraintsMap[relationalEntityType] = constraints;
                foreach (var relationalProperty in relationalEntityType.Properties)
                {
                    int primaryKeyOrdinal;
                    if (_primaryKeyOrdinals.TryGetValue(relationalProperty.Name, out primaryKeyOrdinal))
                    {
                        // add _relational_ property so we can order on the ordinal later
                        primaryKeyProperties.Add(relationalProperty);
                    }

                    Dictionary<string, int> foreignKeyConstraintIdOrdinalMap;
                    if (_foreignKeyOrdinals.TryGetValue(relationalProperty.Name, out foreignKeyConstraintIdOrdinalMap))
                    {
                        // relationalProperty represents (part of) a foreign key
                        foreach (var constraintId in foreignKeyConstraintIdOrdinalMap.Keys)
                        {
                            List<Property> constraintProperties;
                            if (!constraints.TryGetValue(constraintId, out constraintProperties))
                            {
                                constraintProperties = new List<Property>();
                                constraints.Add(constraintId, constraintProperties);
                            }
                            constraintProperties.Add(relationalProperty);
                        }
                    }

                    var codeGenProperty = codeGenEntityType.AddProperty(
                        nameMapper.PropertyToPropertyNameMap[relationalProperty],
                        relationalProperty.ClrType,
                        shadowProperty: true);
                    _relationalPropertyToCodeGenPropertyMap[relationalProperty] = codeGenProperty;
                    ApplyPropertyProperties(codeGenProperty, _tableColumns[relationalProperty.Name]);
                } // end of loop over all relational properties for given EntityType

                if (primaryKeyProperties.Count() > 0)
                {
                    // order the relational properties by their primaryKeyOrdinal, then return a list
                    // of the codeGen properties mapped to each relational property in that order
                    codeGenEntityType.SetPrimaryKey(
                        primaryKeyProperties
                        .OrderBy(p => _primaryKeyOrdinals[p.Name]) // note: for relational property p.Name is its columnId
                        .Select(p => _relationalPropertyToCodeGenPropertyMap[p])
                        .ToList());
                }
                else
                {
                    var errorMessage = Strings.NoPrimaryKeyColumns(
                        codeGenEntityType.Name,
                        _tables[relationalEntityType.Name].SchemaName,
                        _tables[relationalEntityType.Name].TableName);
                    codeGenEntityType.AddAnnotation(AnnotationNameEntityTypeError, errorMessage);
                    _logger.LogWarning(Strings.CannotGenerateEntityType(codeGenEntityType.Name, errorMessage));
                }
            } // end of loop over all relational EntityTypes

            AddForeignKeysToCodeGenModel(codeGenModel);

            return codeGenModel;
        }