예제 #1
0
        public static CSharpClassDefinition GetDatabaseEntityMapperClassDefinition(this EntityFrameworkCoreProject project)
        {
            var classDefinition = new CSharpClassDefinition();

            classDefinition.Namespace = project.GetDataLayerConfigurationsNamespace();

            classDefinition.Name = project.Database.GetDbEntityMapperName();

            classDefinition.BaseClass = "EntityMapper";

            var lines = new List <ILine>();

            if (project.Settings.UseMefForEntitiesMapping)
            {
                classDefinition.Namespaces.Add("System.Composition.Hosting");
                classDefinition.Namespaces.Add("System.Reflection");

                lines.Add(new CommentLine(" Get current assembly"));
                lines.Add(new CodeLine("var currentAssembly = typeof({0}).GetTypeInfo().Assembly;", project.Database.GetDbContextName()));
                lines.Add(new CodeLine());

                lines.Add(new CommentLine(" Get configuration for container from current assembly"));
                lines.Add(new CodeLine("var configuration = new ContainerConfiguration().WithAssembly(currentAssembly);"));
                lines.Add(new CodeLine());

                lines.Add(new CommentLine(" Create container for exports"));
                lines.Add(new CodeLine("using (var container = configuration.CreateContainer())"));
                lines.Add(new CodeLine("{"));
                lines.Add(new CommentLine(1, " Get all definitions that implement IEntityMap interface"));
                lines.Add(new CodeLine(1, "Configurations = container.GetExports<IEntityTypeConfiguration>();"));
                lines.Add(new CodeLine("}"));
            }
            else
            {
                classDefinition.Namespaces.Add("System.Collections.Generic");

                lines.Add(new CodeLine("Configurations = new List<IEntityTypeConfiguration>()"));

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

                for (var i = 0; i < project.Database.Tables.Count; i++)
                {
                    var table = project.Database.Tables[i];

                    lines.Add(new CodeLine(1, "new {0}(){1}", table.GetEntityTypeConfigurationName(), i == project.Database.Tables.Count - 1 ? string.Empty : ","));
                }

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

            classDefinition.Constructors.Add(new ClassConstructorDefinition {
                Lines = lines
            });

            return(classDefinition);
        }
        public static CSharpInterfaceDefinition GetEntityTypeConfigurationInterfaceDefinition(this EntityFrameworkCoreProject project)
        {
            var interfaceDefinition = new CSharpInterfaceDefinition();

            interfaceDefinition.Namespaces.Add("Microsoft.EntityFrameworkCore");

            interfaceDefinition.Namespace = project.GetDataLayerConfigurationsNamespace();

            interfaceDefinition.Name = "IEntityTypeConfiguration";

            interfaceDefinition.Methods.Add(new MethodDefinition("void", "Configure", new ParameterDefinition("ModelBuilder", "modelBuilder")));

            return(interfaceDefinition);
        }
예제 #3
0
        public static CSharpInterfaceDefinition GetEntityMapperInterfaceDefinition(this EntityFrameworkCoreProject project)
        {
            var interfaceDefinition = new CSharpInterfaceDefinition();

            interfaceDefinition.Namespaces.Add("System.Collections.Generic");
            interfaceDefinition.Namespaces.Add("Microsoft.EntityFrameworkCore");

            interfaceDefinition.Namespace = project.GetDataLayerConfigurationsNamespace();

            interfaceDefinition.Name = "IEntityMapper";

            interfaceDefinition.Properties.Add(new PropertyDefinition("IEnumerable<IEntityTypeConfiguration>", "Configurations")
            {
                IsReadOnly = true
            });

            interfaceDefinition.Methods.Add(new MethodDefinition("void", "ConfigureEntities", new ParameterDefinition("ModelBuilder", "modelBuilder")));

            return(interfaceDefinition);
        }
        public static EntityConfigurationClassDefinition GetEntityConfigurationClassDefinition(this EntityFrameworkCoreProject project, IView view)
        {
            var definition = new EntityConfigurationClassDefinition
            {
                Namespaces =
                {
                    "Microsoft.EntityFrameworkCore",
                    "Microsoft.EntityFrameworkCore.Metadata.Builders"
                },
                Namespace      = project.Database.HasDefaultSchema(view) ? project.GetDataLayerConfigurationsNamespace() : project.GetDataLayerConfigurationsNamespace(view.Schema),
                AccessModifier = AccessModifier.Public,
                Name           = project.GetEntityConfigurationName(view),
                Implements     =
                {
                    string.Format("IEntityTypeConfiguration<{0}>", project.GetEntityName(view))
                },
                DbObject = view
            };

            definition.Namespaces.AddUnique(project.GetEntityLayerNamespace(project.Database.HasDefaultSchema(view) ? string.Empty : view.Schema));

            var configLines = new List <ILine>
            {
                new CommentLine(" Set configuration for entity")
            };

            if (string.IsNullOrEmpty(view.Schema))
            {
                configLines.Add(new CodeLine("builder.ToTable(\"{0}\");", view.Name));
            }
            else
            {
                configLines.Add(new CodeLine("builder.ToTable(\"{0}\", \"{1}\");", view.Name, view.Schema));
            }

            configLines.Add(new EmptyLine());

            var primaryKeys = project
                              .Database
                              .Tables
                              .Where(item => item.PrimaryKey != null)
                              .Select(item => item.GetColumnsFromConstraint(item.PrimaryKey).Select(c => c.Name).First())
                              .ToList();

            var result = view.Columns.Where(item => primaryKeys.Contains(item.Name)).ToList();

            if (result.Count == 0)
            {
                result = view.Columns.Where(item => !item.Nullable).ToList();
            }

            configLines.Add(new CommentLine(" Add configuration for entity's key"));

            if (result.Count == 1)
            {
                configLines.Add(new CodeLine("builder.HasKey(p => {0});", string.Format("p.{0}", project.CodeNamingConvention.GetPropertyName(result.First().Name))));
            }
            else
            {
                configLines.Add(new CodeLine("builder.HasKey(p => new {{ {0} }});", string.Join(", ", result.Select(item => string.Format("p.{0}", project.CodeNamingConvention.GetPropertyName(item.Name))))));
            }

            configLines.Add(new EmptyLine());

            configLines.Add(new CommentLine(" Set configuration for columns"));

            for (var i = 0; i < view.Columns.Count; i++)
            {
                var column = view.Columns[i];

                var valueConversion = default(Type);

                if (project.Database.HasTypeMappedToClr(column))
                {
                    var lines = new List <string>
                    {
                        string.Format("Property(p => p.{0})", project.GetPropertyName(view, column))
                    };

                    if (string.Compare(column.Name, project.GetPropertyName(view, column)) != 0)
                    {
                        lines.Add(string.Format("HasColumnName(\"{0}\")", column.Name));
                    }

                    else if (project.Database.ColumnIsDecimal(column))
                    {
                        lines.Add(string.Format("HasColumnType(\"{0}({1}, {2})\")", column.Type, column.Prec, column.Scale));
                    }
                    else if (project.Database.ColumnIsDouble(column) || project.Database.ColumnIsSingle(column))
                    {
                        lines.Add(string.Format("HasColumnType(\"{0}({1})\")", column.Type, column.Prec));
                    }
                    if (project.Database.ColumnIsString(column))
                    {
                        lines.Add(column.Length <= 0 ? string.Format("HasColumnType(\"{0}(max)\")", column.Type) : string.Format("HasColumnType(\"{0}({1})\")", column.Type, column.Length));
                    }
                    else
                    {
                        lines.Add(string.Format("HasColumnType(\"{0}\")", column.Type));
                    }

                    // Use ValueConversionMaps to detect and apply ValueConversion Type based on Type

                    if (project.ValueConversionMaps?.TryGetValue(column.Type, out valueConversion) == true)
                    {
                        lines.Add($"HasConversion(typeof({valueConversion?.FullName}))");
                    }

                    configLines.Add(new CodeLine("builder"));

                    foreach (var line in lines)
                    {
                        configLines.Add(new CodeLine(1, ".{0}", line));
                    }

                    configLines.Add(new CodeLine(1, ";"));
                    configLines.Add(new EmptyLine());
                }
                else
                {
                    var lines = new List <string>
                    {
                        string.Format("builder.Ignore(p => p.{0})", project.GetPropertyName(view, column))
                    };

                    configLines.Add(new CodeLine("{0};", string.Join(".", lines)));
                }
            }

            definition.Methods.Add(new MethodDefinition
            {
                AccessModifier = AccessModifier.Public,
                Type           = "void",
                Name           = "Configure",
                Parameters     =
                {
                    new ParameterDefinition(string.Format("EntityTypeBuilder<{0}>", project.GetEntityName(view)), "builder")
                },
                Lines = configLines
            });

            return(definition);
        }
        public static EntityConfigurationClassDefinition GetEntityConfigurationClassDefinition(this EntityFrameworkCoreProject project, ITable table)
        {
            var definition = new EntityConfigurationClassDefinition
            {
                Namespaces =
                {
                    "Microsoft.EntityFrameworkCore",
                    "Microsoft.EntityFrameworkCore.Metadata.Builders"
                },
                Namespace      = project.Database.HasDefaultSchema(table) ? project.GetDataLayerConfigurationsNamespace() : project.GetDataLayerConfigurationsNamespace(table.Schema),
                AccessModifier = AccessModifier.Public,
                Name           = project.GetEntityConfigurationName(table),
                DbObject       = table
            };

            definition.Namespaces.AddUnique(project.GetEntityLayerNamespace(project.Database.HasDefaultSchema(table) ? string.Empty : table.Schema));

            // todo: Check logic to build property's name

            var propertyType = "";

            if (table.HasSameEnclosingName())
            {
                propertyType = string.Join(".", (new string[] { project.ProjectNamespaces.EntityLayer, project.Database.HasDefaultSchema(table) ? string.Empty : table.Schema, project.GetEntityName(table) }).Where(item => !string.IsNullOrEmpty(item)));
            }
            else
            {
                propertyType = project.GetEntityName(table);
            }

            definition.Implements.Add(string.Format("IEntityTypeConfiguration<{0}>", propertyType));

            var configLines = new List <ILine>
            {
                new CommentLine(" Set configuration for entity")
            };

            if (string.IsNullOrEmpty(table.Schema))
            {
                configLines.Add(new CodeLine("builder.ToTable(\"{0}\");", table.Name));
            }
            else
            {
                configLines.Add(new CodeLine("builder.ToTable(\"{0}\", \"{1}\");", table.Name, table.Schema));
            }

            configLines.Add(new EmptyLine());

            var columns = default(List <Column>);

            if (table.PrimaryKey == null || table.PrimaryKey.Key.Count == 0)
            {
                configLines.Add(LineHelper.Warning("Add configuration for entity's key"));
                configLines.Add(new EmptyLine());
            }
            else
            {
                configLines.Add(new CommentLine(" Set key for entity"));

                if (table.PrimaryKey.Key.Count == 1)
                {
                    configLines.Add(new CodeLine("builder.HasKey(p => p.{0});", project.CodeNamingConvention.GetPropertyName(table.PrimaryKey.Key[0])));
                    configLines.Add(new EmptyLine());
                }
                else if (table.PrimaryKey.Key.Count > 1)
                {
                    configLines.Add(new CodeLine("builder.HasKey(p => new {{ {0} }});", string.Join(", ", table.PrimaryKey.Key.Select(item => string.Format("p.{0}", project.CodeNamingConvention.GetPropertyName(item))))));
                    configLines.Add(new EmptyLine());
                }
            }

            if (table.Identity != null)
            {
                configLines.Add(new CommentLine(" Set identity for entity (auto increment)"));
                configLines.Add(new CodeLine("builder.Property(p => p.{0}).UseSqlServerIdentityColumn();", project.CodeNamingConvention.GetPropertyName(table.Identity.Name)));
                configLines.Add(new EmptyLine());
            }

            columns = table.Columns;

            configLines.Add(new CommentLine(" Set configuration for columns"));

            for (var i = 0; i < columns.Count; i++)
            {
                var column = columns[i];

                var valueConversion = default(Type);

                if (project.Database.HasTypeMappedToClr(column))
                {
                    var lines = new List <string>
                    {
                        string.Format("Property(p => p.{0})", project.GetPropertyName(table, column))
                    };

                    if (string.Compare(column.Name, project.GetPropertyName(table, column)) != 0)
                    {
                        lines.Add(string.Format("HasColumnName(\"{0}\")", column.Name));
                    }

                    if (project.Database.ColumnIsByteArray(column))
                    {
                        lines.Add(string.Format("HasColumnType(\"{0}({1})\")", column.Type, column.Length));
                    }
                    else if (project.Database.ColumnIsDecimal(column))
                    {
                        lines.Add(string.Format("HasColumnType(\"{0}({1}, {2})\")", column.Type, column.Prec, column.Scale));
                    }
                    else if (project.Database.ColumnIsDouble(column) || project.Database.ColumnIsSingle(column))
                    {
                        lines.Add(string.Format("HasColumnType(\"{0}({1})\")", column.Type, column.Prec));
                    }
                    else if (project.Database.ColumnIsString(column))
                    {
                        if (column.Length <= 0)
                        {
                            lines.Add(string.Format("HasColumnType(\"{0}(max)\")", column.Type));
                        }
                        else
                        {
                            lines.Add(string.Format("HasColumnType(\"{0}\")", column.Type));
                            lines.Add(string.Format("HasMaxLength({0})", column.Length));
                        }
                    }
                    else
                    {
                        lines.Add(string.Format("HasColumnType(\"{0}\")", column.Type));
                    }

                    // Use ValueConversionMaps to detect and apply ValueConversion Type based on Type

                    if (project.ValueConversionMaps.TryGetValue(column.Type, out valueConversion) == true)
                    {
                        lines.Add($".HasConversion(typeof({valueConversion?.FullName}))");
                    }

                    if (!column.Nullable)
                    {
                        lines.Add("IsRequired()");
                    }

                    configLines.Add(new CodeLine("builder"));

                    foreach (var line in lines)
                    {
                        configLines.Add(new CodeLine(1, ".{0}", line));
                    }

                    configLines.Add(new CodeLine(1, ";"));
                    configLines.Add(new EmptyLine());
                }
                else
                {
                    configLines.Add(new CodeLine("builder.Ignore(p => p.{0});", project.GetPropertyName(table, column)));
                    configLines.Add(new EmptyLine());
                }
            }

            var projectSelection = project.GetSelection(table);

            for (var i = 0; i < columns.Count; i++)
            {
                var column = columns[i];

                if (!string.IsNullOrEmpty(projectSelection.Settings.ConcurrencyToken) && string.Compare(column.Name, projectSelection.Settings.ConcurrencyToken) == 0)
                {
                    configLines.Add(new CommentLine(" Set concurrency token for entity"));
                    configLines.Add(new CodeLine("builder"));
                    configLines.Add(new CodeLine(1, ".Property(p => p.{0})", project.GetPropertyName(table, column)));
                    configLines.Add(new CodeLine(1, ".ValueGeneratedOnAddOrUpdate()"));
                    configLines.Add(new CodeLine(1, ".IsConcurrencyToken();"));
                    configLines.Add(new EmptyLine());
                }
            }

            if (projectSelection.Settings.AddConfigurationForUniquesInFluentAPI && table.Uniques.Count > 0)
            {
                configLines.Add(new CommentLine(" Add configuration for uniques"));
                configLines.Add(new EmptyLine());

                foreach (var unique in table.Uniques)
                {
                    configLines.Add(new CodeLine("builder"));

                    if (unique.Key.Count == 1)
                    {
                        configLines.Add(new CodeLine(1, ".HasIndex(p => p.{0})", project.CodeNamingConvention.GetPropertyName(unique.Key.First())));
                        configLines.Add(new CodeLine(1, ".IsUnique()"));
                    }
                    else
                    {
                        configLines.Add(new CodeLine(1, ".HasIndex(p => new {{ {0} }})", string.Join(", ", unique.Key.Select(item => string.Format("p.{0}", project.CodeNamingConvention.GetPropertyName(item))))));
                        configLines.Add(new CodeLine(1, ".IsUnique()"));
                    }

                    configLines.Add(new CodeLine(1, ".HasName(\"{0}\");", unique.ConstraintName));
                    configLines.Add(new EmptyLine());
                }
            }

            if (projectSelection.Settings.AddConfigurationForForeignKeysInFluentAPI && projectSelection.Settings.DeclareNavigationProperties && table.ForeignKeys.Count > 0)
            {
                configLines.Add(new CommentLine(" Add configuration for foreign keys"));
                configLines.Add(new EmptyLine());

                foreach (var foreignKey in table.ForeignKeys)
                {
                    var foreignTable = project.Database.FindTable(foreignKey.References);

                    if (foreignTable == null || foreignKey.Key.Count == 0)
                    {
                        continue;
                    }

                    if (foreignKey.Key.Count == 1)
                    {
                        var foreignProperty = foreignKey.GetParentNavigationProperty(foreignTable, project);

                        configLines.Add(new CodeLine("builder"));
                        configLines.Add(new CodeLine(1, ".HasOne(p => p.{0})", foreignProperty.Name));
                        configLines.Add(new CodeLine(1, ".WithMany(b => b.{0})", project.GetNavigationPropertyName(table)));
                        configLines.Add(new CodeLine(1, ".HasForeignKey(p => {0})", string.Format("p.{0}", project.CodeNamingConvention.GetPropertyName(foreignKey.Key.First()))));
                        configLines.Add(new CodeLine(1, ".HasConstraintName(\"{0}\");", foreignKey.ConstraintName));
                        configLines.Add(new EmptyLine());
                    }
                    else
                    {
                        configLines.Add(LineHelper.Warning(" Add logic for foreign key with multiple key"));
                    }
                }
            }

            if (projectSelection.Settings.AddConfigurationForDefaultsInFluentAPI && table.Defaults.Count > 0)
            {
                configLines.Add(new CommentLine(" Add configuration for defaults"));
                configLines.Add(new EmptyLine());

                foreach (var def in table.Defaults)
                {
                    var propertyName = def.Key.First();

                    configLines.Add(new CodeLine("builder"));
                    configLines.Add(new CodeLine(1, ".Property(p => p.{0})", project.GetPropertyName(propertyName)));
                    configLines.Add(new CodeLine(1, ".HasDefaultValueSql(\"{0}\");", def.Value));
                    configLines.Add(new EmptyLine());
                }
            }

            definition.Methods.Add(new MethodDefinition
            {
                AccessModifier = AccessModifier.Public,
                Type           = "void",
                Name           = "Configure",
                Parameters     =
                {
                    new ParameterDefinition(string.Format("EntityTypeBuilder<{0}>", propertyType), "builder")
                },
                Lines = configLines
            });

            return(definition);
        }
        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);
        }
예제 #7
0
        public static CSharpClassDefinition GetEntityTypeConfigurationClassDefinition(this EntityFrameworkCoreProject project, IView view)
        {
            var classDefinition = new CSharpClassDefinition();

            if (project.Settings.UseMefForEntitiesMapping)
            {
                classDefinition.Namespaces.Add("System.Composition");

                classDefinition.Attributes.Add(new MetadataAttribute("Export", "typeof(IEntityTypeConfiguration)"));
            }

            classDefinition.Namespaces.Add("Microsoft.EntityFrameworkCore");

            classDefinition.Namespaces.AddUnique(project.GetEntityLayerNamespace(view.HasDefaultSchema() ? string.Empty : view.Schema));

            classDefinition.Namespace = project.GetDataLayerConfigurationsNamespace();

            classDefinition.Name = view.GetEntityTypeConfigurationName();

            classDefinition.Implements.Add("IEntityTypeConfiguration");

            var mapLines = new List <ILine>();

            mapLines.Add(new CodeLine("modelBuilder.Entity<{0}>(builder =>", view.GetSingularName()));
            mapLines.Add(new CodeLine("{"));

            mapLines.Add(new CommentLine(1, " Set configuration for entity"));

            if (string.IsNullOrEmpty(view.Schema))
            {
                mapLines.Add(new CodeLine(1, "builder.ToTable(\"{0}\");", view.Name));
            }
            else
            {
                mapLines.Add(new CodeLine(1, "builder.ToTable(\"{0}\", \"{1}\");", view.Name, view.Schema));
            }

            mapLines.Add(new CodeLine());

            var primaryKeys = project.Database.Tables.Where(item => item.PrimaryKey != null).Select(item => item.PrimaryKey?.GetColumns(item).Select(c => c.Name).First()).ToList();

            var result = view.Columns.Where(item => !item.Nullable && primaryKeys.Contains(item.Name)).ToList();

            if (result.Count == 0)
            {
                result = view.Columns.Where(item => !item.Nullable).ToList();
            }

            mapLines.Add(new CommentLine(1, " Add configuration for entity's key"));
            mapLines.Add(new CodeLine(1, "builder.HasKey(p => new {{ {0} }});", string.Join(", ", result.Select(item => string.Format("p.{0}", classDefinition.NamingConvention.GetPropertyName(item.Name))))));
            mapLines.Add(new CodeLine());

            mapLines.Add(new CommentLine(1, " Set configuration for columns"));

            for (var i = 0; i < view.Columns.Count; i++)
            {
                var column = view.Columns[i];

                var lines = new List <string>()
                {
                    string.Format("builder.Property(p => p.{0})", column.GetPropertyName())
                };

                if (string.Compare(column.Name, column.GetPropertyName()) != 0)
                {
                    lines.Add(string.Format("HasColumnName(\"{0}\")", column.Name));
                }

                if (column.IsString())
                {
                    lines.Add(column.Length == 0 ? string.Format("HasColumnType(\"{0}(max)\")", column.Type) : string.Format("HasColumnType(\"{0}({1})\")", column.Type, column.Length));
                }
                else if (column.IsDecimal())
                {
                    lines.Add(string.Format("HasColumnType(\"{0}({1}, {2})\")", column.Type, column.Prec, column.Scale));
                }
                else if (column.IsDouble() || column.IsSingle())
                {
                    lines.Add(string.Format("HasColumnType(\"{0}({1})\")", column.Type, column.Prec));
                }
                else
                {
                    lines.Add(string.Format("HasColumnType(\"{0}\")", column.Type));
                }

                mapLines.Add(new CodeLine(1, "{0};", string.Join(".", lines)));
            }

            mapLines.Add(new CodeLine("});"));

            var mapMethod = new MethodDefinition("void", "Configure", new ParameterDefinition("ModelBuilder", "modelBuilder"))
            {
                Lines = mapLines
            };

            classDefinition.Methods.Add(mapMethod);

            return(classDefinition);
        }
예제 #8
0
        public static CSharpClassDefinition GetEntityTypeConfigurationClassDefinition(this EntityFrameworkCoreProject project, ITable table)
        {
            var classDefinition = new CSharpClassDefinition();

            if (project.Settings.UseMefForEntitiesMapping)
            {
                classDefinition.Namespaces.Add("System.Composition");

                classDefinition.Attributes.Add(new MetadataAttribute("Export", "typeof(IEntityTypeConfiguration)"));
            }

            classDefinition.Namespaces.Add("Microsoft.EntityFrameworkCore");

            classDefinition.Namespaces.AddUnique(project.GetEntityLayerNamespace(table.HasDefaultSchema() ? string.Empty : table.Schema));

            classDefinition.Namespace = project.GetDataLayerConfigurationsNamespace();

            classDefinition.Name = table.GetEntityTypeConfigurationName();

            classDefinition.Implements.Add("IEntityTypeConfiguration");

            var mapLines = new List <ILine>();

            mapLines.Add(new CodeLine("modelBuilder.Entity<{0}>(builder =>", table.GetSingularName()));
            mapLines.Add(new CodeLine("{"));

            mapLines.Add(new CommentLine(1, " Set configuration for entity"));

            if (string.IsNullOrEmpty(table.Schema))
            {
                mapLines.Add(new CodeLine(1, "builder.ToTable(\"{0}\");", table.Name));
            }
            else
            {
                mapLines.Add(new CodeLine(1, "builder.ToTable(\"{0}\", \"{1}\");", table.Name, table.Schema));
            }

            mapLines.Add(new CodeLine());

            var columns = default(List <Column>);

            if (table.PrimaryKey == null || table.PrimaryKey.Key.Count == 0)
            {
                mapLines.Add(LineHelper.Warning("Add configuration for entity's key"));
                mapLines.Add(new CodeLine());
            }
            else
            {
                mapLines.Add(new CommentLine(1, " Set key for entity"));

                if (table.PrimaryKey.Key.Count == 1)
                {
                    mapLines.Add(new CodeLine(1, "builder.HasKey(p => p.{0});", classDefinition.NamingConvention.GetPropertyName(table.PrimaryKey.Key[0])));
                    mapLines.Add(new CodeLine());
                }
                else if (table.PrimaryKey.Key.Count > 1)
                {
                    mapLines.Add(new CodeLine(1, "builder.HasKey(p => new {{ {0} }});", string.Join(", ", table.PrimaryKey.Key.Select(item => string.Format("p.{0}", classDefinition.NamingConvention.GetPropertyName(item))))));
                    mapLines.Add(new CodeLine());
                }
            }

            if (table.Identity != null)
            {
                mapLines.Add(new CommentLine(1, " Set identity for entity (auto increment)"));
                mapLines.Add(new CodeLine(1, "builder.Property(p => p.{0}).UseSqlServerIdentityColumn();", classDefinition.NamingConvention.GetPropertyName(table.Identity.Name)));
                mapLines.Add(new CodeLine());
            }

            columns = table.Columns;

            mapLines.Add(new CommentLine(1, " Set configuration for columns"));

            for (var i = 0; i < columns.Count; i++)
            {
                var column = columns[i];

                var lines = new List <string>()
                {
                    string.Format("builder.Property(p => p.{0})", column.GetPropertyName())
                };

                if (string.Compare(column.Name, column.GetPropertyName()) != 0)
                {
                    lines.Add(string.Format("HasColumnName(\"{0}\")", column.Name));
                }

                if (column.IsString())
                {
                    lines.Add(column.Length == 0 ? string.Format("HasColumnType(\"{0}(max)\")", column.Type) : string.Format("HasColumnType(\"{0}({1})\")", column.Type, column.Length));
                }
                else if (column.IsDecimal())
                {
                    lines.Add(string.Format("HasColumnType(\"{0}({1}, {2})\")", column.Type, column.Prec, column.Scale));
                }
                else if (column.IsDouble() || column.IsSingle())
                {
                    lines.Add(string.Format("HasColumnType(\"{0}({1})\")", column.Type, column.Prec));
                }
                else
                {
                    lines.Add(string.Format("HasColumnType(\"{0}\")", column.Type));
                }

                if (!column.Nullable)
                {
                    lines.Add("IsRequired()");
                }

                mapLines.Add(new CodeLine(1, "{0};", string.Join(".", lines)));
            }

            mapLines.Add(new CodeLine());

            for (var i = 0; i < columns.Count; i++)
            {
                var column = columns[i];

                if (!string.IsNullOrEmpty(project.Settings.ConcurrencyToken) && string.Compare(column.Name, project.Settings.ConcurrencyToken) == 0)
                {
                    mapLines.Add(new CommentLine(1, " Set concurrency token for entity"));
                    mapLines.Add(new CodeLine(1, "builder"));
                    mapLines.Add(new CodeLine(2, ".Property(p => p.{0})", column.GetPropertyName()));
                    mapLines.Add(new CodeLine(2, ".ValueGeneratedOnAddOrUpdate()"));
                    mapLines.Add(new CodeLine(2, ".IsConcurrencyToken();"));
                    mapLines.Add(new CodeLine());
                }
            }

            if (table.Uniques.Count > 0)
            {
                mapLines.Add(new CommentLine(1, " Add configuration for uniques"));

                foreach (var unique in table.Uniques)
                {
                    mapLines.Add(new CodeLine(1, "builder"));

                    if (unique.Key.Count == 1)
                    {
                        mapLines.Add(new CodeLine(2, ".HasIndex(p => p.{0})", classDefinition.NamingConvention.GetPropertyName(unique.Key.First())));
                        mapLines.Add(new CodeLine(2, ".IsUnique()"));
                    }
                    else
                    {
                        mapLines.Add(new CodeLine(2, ".HasIndex(p => new {{ {0} }})", string.Join(", ", table.PrimaryKey.Key.Select(item => string.Format("p.{0}", classDefinition.NamingConvention.GetPropertyName(item))))));
                        mapLines.Add(new CodeLine(2, ".IsUnique()"));
                    }

                    mapLines.Add(new CodeLine(2, ".HasName(\"{0}\");", unique.ConstraintName));
                    mapLines.Add(new CodeLine());
                }
            }

            if (table.ForeignKeys.Count > 0)
            {
                mapLines.Add(new CommentLine(1, " Add configuration for foreign keys"));

                foreach (var foreignKey in table.ForeignKeys)
                {
                    var foreignTable = project.Database.FindTableByFullName(foreignKey.References);

                    if (foreignTable == null)
                    {
                        continue;
                    }

                    if (foreignKey.Key.Count == 0)
                    {
                        continue;
                    }
                    else if (foreignKey.Key.Count == 1)
                    {
                        var foreignProperty = foreignKey.GetParentNavigationProperty(project, foreignTable);

                        mapLines.Add(new CodeLine(1, "builder"));
                        mapLines.Add(new CodeLine(2, ".HasOne(p => p.{0})", foreignProperty.Name));
                        mapLines.Add(new CodeLine(2, ".WithMany(b => b.{0})", table.GetPluralName()));
                        mapLines.Add(new CodeLine(2, ".HasForeignKey(p => {0})", string.Format("p.{0}", classDefinition.NamingConvention.GetPropertyName(foreignKey.Key[0]))));
                        mapLines.Add(new CodeLine(2, ".HasConstraintName(\"{0}\");", foreignKey.ConstraintName));
                        mapLines.Add(new CodeLine());
                    }
                    else
                    {
                        mapLines.Add(LineHelper.Warning(" Add logic for foreign key with multiple key"));
                    }
                }
            }

            mapLines.Add(new CodeLine("});"));

            var mapMethod = new MethodDefinition("void", "Configure", new ParameterDefinition("ModelBuilder", "modelBuilder"))
            {
                Lines = mapLines
            };

            classDefinition.Methods.Add(mapMethod);

            return(classDefinition);
        }
예제 #9
0
        public static CSharpClassDefinition GetEntityTypeConfigurationClassDefinition(this EntityFrameworkCoreProject project, IView view)
        {
            var definition = new CSharpClassDefinition
            {
                Namespaces =
                {
                    "Microsoft.EntityFrameworkCore",
                    "Microsoft.EntityFrameworkCore.Metadata.Builders"
                },
                Namespace  = project.GetDataLayerConfigurationsNamespace(),
                Name       = project.GetEntityConfigurationName(view),
                Implements =
                {
                    string.Format("IEntityTypeConfiguration<{0}>", project.GetEntityName(view))
                }
            };

            definition.Namespaces.AddUnique(project.GetEntityLayerNamespace(project.Database.HasDefaultSchema(view) ? string.Empty : view.Schema));

            var configLines = new List <ILine>
            {
                new CommentLine(" Set configuration for entity")
            };

            if (string.IsNullOrEmpty(view.Schema))
            {
                configLines.Add(new CodeLine("builder.ToTable(\"{0}\");", view.Name));
            }
            else
            {
                configLines.Add(new CodeLine("builder.ToTable(\"{0}\", \"{1}\");", view.Name, view.Schema));
            }

            configLines.Add(new CodeLine());

            var primaryKeys = project.Database.Tables.Where(item => item.PrimaryKey != null).Select(item => item.GetColumnsFromConstraint(item.PrimaryKey).Select(c => c.Name).First()).ToList();

            var result = view.Columns.Where(item => primaryKeys.Contains(item.Name)).ToList();

            if (result.Count == 0)
            {
                result = view.Columns.Where(item => !item.Nullable).ToList();
            }

            configLines.Add(new CommentLine(" Add configuration for entity's key"));
            configLines.Add(new CodeLine("builder.HasKey(p => new {{ {0} }});", string.Join(", ", result.Select(item => string.Format("p.{0}", definition.NamingConvention.GetPropertyName(item.Name))))));
            configLines.Add(new CodeLine());

            configLines.Add(new CommentLine(" Set configuration for columns"));

            for (var i = 0; i < view.Columns.Count; i++)
            {
                var column = view.Columns[i];

                if (project.Database.HasTypeMappedToClr(column))
                {
                    var lines = new List <string>
                    {
                        string.Format("builder.Property(p => p.{0})", view.GetPropertyNameHack(column))
                    };

                    if (string.Compare(column.Name, column.GetPropertyName()) != 0)
                    {
                        lines.Add(string.Format("HasColumnName(\"{0}\")", column.Name));
                    }

                    if (project.Database.ColumnIsString(column))
                    {
                        lines.Add(column.Length <= 0 ? string.Format("HasColumnType(\"{0}(max)\")", column.Type) : string.Format("HasColumnType(\"{0}({1})\")", column.Type, column.Length));
                    }
                    else if (project.Database.ColumnIsDecimal(column))
                    {
                        lines.Add(string.Format("HasColumnType(\"{0}({1}, {2})\")", column.Type, column.Prec, column.Scale));
                    }
                    else if (project.Database.ColumnIsDouble(column) || project.Database.ColumnIsSingle(column))
                    {
                        lines.Add(string.Format("HasColumnType(\"{0}({1})\")", column.Type, column.Prec));
                    }
                    else
                    {
                        lines.Add(string.Format("HasColumnType(\"{0}\")", column.Type));
                    }

                    configLines.Add(new CodeLine("{0};", string.Join(".", lines)));
                }
                else
                {
                    var lines = new List <string>
                    {
                        string.Format("builder.Ignore(p => p.{0})", view.GetPropertyNameHack(column))
                    };

                    configLines.Add(new CodeLine("{0};", string.Join(".", lines)));
                }
            }

            definition.Methods.Add(new MethodDefinition("void", "Configure", new ParameterDefinition(string.Format("EntityTypeBuilder<{0}>", project.GetEntityName(view)), "builder"))
            {
                Lines = configLines
            });

            return(definition);
        }