public static EntityClassDefinition GetEntityClassDefinition(this EntityFrameworkCoreProject project, StoredProcedure storedProcedure)
        {
            var definition = new EntityClassDefinition
            {
                Namespaces =
                {
                    "System"
                },
                Namespace      = project.Database.HasDefaultSchema(storedProcedure) ? project.GetEntityLayerNamespace() : project.GetEntityLayerNamespace(storedProcedure.Schema),
                AccessModifier = AccessModifier.Public,
                Name           = project.GetEntityResultName(storedProcedure),
                IsPartial      = true,
                Constructors   =
                {
                    new ClassConstructorDefinition
                    {
                        AccessModifier = AccessModifier.Public
                    }
                },
                DbObject = storedProcedure
            };

            if (!string.IsNullOrEmpty(storedProcedure.Description))
            {
                definition.Documentation.Summary = storedProcedure.Description;
            }

            var projectSelection = project.GetSelection(storedProcedure);

            if (storedProcedure.FirstResultSetsForObject.Count == 0)
            {
                // todo: Add logic to stored procedures with no result set
            }
            else
            {
                foreach (var property in storedProcedure.FirstResultSetsForObject)
                {
                    var propertyType = project.Database.ResolveDatabaseType(property.SystemTypeName);

                    definition.Properties.Add(new PropertyDefinition
                    {
                        AccessModifier = AccessModifier.Public,
                        Type           = propertyType,
                        Name           = project.GetPropertyName(property.Name),
                        IsAutomatic    = true
                    });
                }
            }

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

            return(definition);
        }
        public static EntityClassDefinition GetEntityClassDefinition(this EntityFrameworkCoreProject project, TableFunction tableFunction)
        {
            var definition = new EntityClassDefinition
            {
                Namespaces =
                {
                    "System"
                },
                Namespace      = project.Database.HasDefaultSchema(tableFunction) ? project.GetEntityLayerNamespace() : project.GetEntityLayerNamespace(tableFunction.Schema),
                AccessModifier = AccessModifier.Public,
                Name           = project.GetEntityResultName(tableFunction),
                IsPartial      = true,
                Constructors   =
                {
                    new ClassConstructorDefinition
                    {
                        AccessModifier = AccessModifier.Public
                    }
                },
                DbObject = tableFunction
            };

            if (!string.IsNullOrEmpty(tableFunction.Description))
            {
                definition.Documentation.Summary = tableFunction.Description;
            }

            var projectSelection = project.GetSelection(tableFunction);

            foreach (var column in tableFunction.Columns)
            {
                var type = project.Database.ResolveDatabaseType(column);

                definition.Properties.Add(new PropertyDefinition
                {
                    AccessModifier = AccessModifier.Public,
                    Type           = type,
                    Name           = project.GetPropertyName(column.Name),
                    IsAutomatic    = true
                });
            }

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

            return(definition);
        }
        private static MethodDefinition GetOnModelCreatingMethod(EntityFrameworkCoreProject project)
        {
            var lines = new List <ILine>();

            var selection = project.GlobalSelection();

            if (selection.Settings.UseDataAnnotations)
            {
                var primaryKeys = project
                                  .Database
                                  .Tables
                                  .Where(item => item.PrimaryKey != null)
                                  .Select(item => item.GetColumnsFromConstraint(item.PrimaryKey).Select(key => key.Name).First())
                                  .ToList();

                foreach (var view in project.Database.Views)
                {
                    var result = view.Columns.Where(item => primaryKeys.Contains(item.Name)).ToList();

                    if (result.Count == 0)
                    {
                        lines.Add(
                            new CodeLine("modelBuilder.Entity<{0}>().HasKey(e => new {{ {1} }});", project.GetEntityName(view), string.Join(", ", view.Columns.Select(item => string.Format("e.{0}", project.GetPropertyName(view, item))))));

                        lines.Add(new EmptyLine());
                    }
                    else
                    {
                        lines.Add(
                            new CodeLine("modelBuilder.Entity<{0}>().HasKey(e => new {{ {1} }});", project.GetEntityName(view), string.Join(", ", result.Select(item => string.Format("e.{0}", project.GetPropertyName(view, item))))));

                        lines.Add(new EmptyLine());
                    }
                }
            }
            else
            {
                if (project.Database.Tables.Count > 0)
                {
                    lines.Add(new CommentLine(" Apply all configurations for tables"));
                    lines.Add(new EmptyLine());

                    lines.Add(new CodeLine("modelBuilder"));

                    foreach (var table in project.Database.Tables)
                    {
                        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.GetEntityConfigurationName(table) : project.GetFullEntityConfigurationName(table);

                        lines.Add(new CodeLine(1, ".ApplyConfiguration(new {0}())", name));
                    }

                    lines.Add(new CodeLine(";"));

                    lines.Add(new EmptyLine());
                }

                if (project.Database.Views.Count > 0)
                {
                    lines.Add(new CommentLine(" Apply all configurations for views"));
                    lines.Add(new EmptyLine());

                    lines.Add(new CodeLine("modelBuilder"));

                    foreach (var view in project.Database.Views)
                    {
                        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.GetEntityConfigurationName(view) : project.GetFullEntityConfigurationName(view);

                        lines.Add(new CodeLine(1, ".ApplyConfiguration(new {0}())", name));
                    }

                    lines.Add(new CodeLine(";"));
                    lines.Add(new EmptyLine());
                }

                if (project.Database.TableFunctions.Count > 0)
                {
                    lines.Add(new CommentLine(" Register query types for table functions"));
                    lines.Add(new EmptyLine());

                    foreach (var view in project.Database.TableFunctions)
                    {
                        lines.Add(new CodeLine("modelBuilder.Query<{0}>();", project.GetEntityResultName(view)));
                    }

                    lines.Add(new EmptyLine());
                }

                if (project.Database.StoredProcedures.Count > 0)
                {
                    lines.Add(new CommentLine(" Register query types for stored procedures"));
                    lines.Add(new EmptyLine());

                    foreach (var view in project.Database.StoredProcedures)
                    {
                        lines.Add(new CodeLine("modelBuilder.Query<{0}>();", project.GetEntityResultName(view)));
                    }

                    lines.Add(new EmptyLine());
                }
            }

            lines.Add(new CodeLine("base.OnModelCreating(modelBuilder);"));

            return(new MethodDefinition
            {
                AccessModifier = AccessModifier.Protected,
                Type = "void",
                Name = "OnModelCreating",
                Parameters =
                {
                    new ParameterDefinition("ModelBuilder", "modelBuilder")
                },
                IsOverride = true,
                Lines = lines
            });
        }