public static DbContextClassDefinition GetDbContextClassDefinition(this EntityFrameworkCoreProject project, ProjectSelection <EntityFrameworkCoreProjectSettings> projectSelection)
        {
            var definition = new DbContextClassDefinition
            {
                Namespaces =
                {
                    "System",
                    "Microsoft.EntityFrameworkCore",
                    project.GetEntityLayerNamespace()
                },
                Namespace      = project.GetDataLayerNamespace(),
                AccessModifier = AccessModifier.Public,
                Name           = project.GetDbContextName(project.Database),
                BaseClass      = "DbContext"
            };

            if (!projectSelection.Settings.UseDataAnnotations)
            {
                definition.Namespaces.Add(project.GetDataLayerConfigurationsNamespace());
            }

            definition.Constructors.Add(new ClassConstructorDefinition
            {
                AccessModifier = AccessModifier.Public,
                Parameters     =
                {
                    new ParameterDefinition(string.Format("DbContextOptions<{0}>", definition.Name), "options")
                },
                Invocation = "base(options)"
            });

            definition.Methods.Add(GetOnModelCreatingMethod(project));

            foreach (var table in project.Database.Tables)
            {
                if (!project.Database.HasDefaultSchema(table))
                {
                    definition.Namespaces.AddUnique(project.GetEntityLayerNamespace(table.Schema));
                }

                var existingViews = project.Database.Views.Count(item => item.Name == table.Name);

                var genericTypeName = existingViews == 0 ? project.GetEntityName(table) : project.GetFullEntityName(table);
                var name            = existingViews == 0 ? project.GetDbSetPropertyName(table) : project.GetFullDbSetPropertyName(table);

                definition.Properties.Add(
                    new PropertyDefinition
                {
                    AccessModifier = AccessModifier.Public,
                    Type           = string.Format("DbSet<{0}>", genericTypeName),
                    Name           = name,
                    IsAutomatic    = true
                }
                    );
            }

            foreach (var view in project.Database.Views)
            {
                if (!project.Database.HasDefaultSchema(view))
                {
                    definition.Namespaces.AddUnique(project.GetEntityLayerNamespace(view.Schema));
                }

                var existingTables = project.Database.Tables.Count(item => item.Name == view.Name);

                var genericTypeName = existingTables == 0 ? project.GetEntityName(view) : project.GetFullEntityName(view);
                var name            = existingTables == 0 ? project.GetDbSetPropertyName(view) : project.GetFullDbSetPropertyName(view);

                definition.Properties.Add(
                    new PropertyDefinition
                {
                    AccessModifier = AccessModifier.Public,
                    Type           = string.Format("DbSet<{0}>", genericTypeName),
                    Name           = name,
                    IsAutomatic    = true
                }
                    );
            }

            foreach (var table in project.Database.Tables)
            {
                if (!projectSelection.Settings.UseDataAnnotations && !project.Database.HasDefaultSchema(table))
                {
                    definition.Namespaces.AddUnique(project.GetDataLayerConfigurationsNamespace(table.Schema));
                }
            }

            foreach (var view in project.Database.Views)
            {
                if (!projectSelection.Settings.UseDataAnnotations && !project.Database.HasDefaultSchema(view))
                {
                    definition.Namespaces.AddUnique(project.GetDataLayerConfigurationsNamespace(view.Schema));
                }
            }

            foreach (var scalarFunction in project.Database.ScalarFunctions)
            {
                var parameterType = string.Empty;

                if (project.Database.HasTypeMappedToClr(scalarFunction.Parameters[0]))
                {
                    var clrType = project.Database.GetClrMapForType(scalarFunction.Parameters[0]);

                    parameterType = clrType.AllowClrNullable ? string.Format("{0}?", clrType.GetClrType().Name) : clrType.GetClrType().Name;
                }
                else
                {
                    parameterType = "object";
                }

                var method = new MethodDefinition
                {
                    Attributes =
                    {
                        new MetadataAttribute("DbFunction")
                        {
                            Sets =
                            {
                                new MetadataAttributeSet("FunctionName", string.Format("\"{0}\"", scalarFunction.Name)),
                                new MetadataAttributeSet("Schema",       string.Format("\"{0}\"", scalarFunction.Schema))
                            }
                        }
                    },
                    IsStatic       = true,
                    Type           = parameterType,
                    AccessModifier = AccessModifier.Public,
                    Name           = project.GetScalarFunctionMethodName(scalarFunction),
                    Lines          =
                    {
                        new CodeLine("throw new Exception();")
                    }
                };

                var parameters = scalarFunction.Parameters.Where(item => !string.IsNullOrEmpty(item.Name)).ToList();

                foreach (var parameter in parameters)
                {
                    var propertyType = project.Database.ResolveDatabaseType(parameter);

                    method.Parameters.Add(new ParameterDefinition(parameterType, project.GetPropertyName(parameter)));
                }

                definition.Methods.Add(method);
            }

            if (projectSelection.Settings.SimplifyDataTypes)
            {
                definition.SimplifyDataTypes();
            }

            return(definition);
        }