sjh37 / EntityFramework-Reverse-POCO-Code-First-Generator

EntityFramework Reverse POCO Code First Generator - Beautifully generated code that is fully customisable. This generator creates code as if you reverse engineered a database and lovingly created the code by hand. It is free to academics (you need a .edu or a .ac email address), not free for commercial use. Obtain your licence from
https://www.reversepoco.co.uk/
Other
710 stars 227 forks source link

Enum property type replacement enhancements #739

Closed matt-neubert closed 2 years ago

matt-neubert commented 2 years ago

I'm not sure if this is a feature request or a general how to question. I like to identify enum tables by naming conventions for example it may start with REF_ or it may end in _LUT. What I would like to do is create this list dynamically. The PK of this table would be enum value and the table always has Name column which is the enum name. (Maybe even any other columns in the table would become attributes on the enum ... but that would be bonus). This is not only for creating the enum but also for the enum property type replacement. In the UpdateColumn method I would like to have a way to check to see if the column is an FK column and if it is to be able to find the parent column's table name and also check if it conformed to the naming convention. If I could get to that info I would be able to add it to enumDefinitions then the type could be replaced by the enum type.

These were just my thoughts but would be open to other ways to automate this. When we were working back on version 2.8 at a former employer, we created a property on the Column class named ParentColumn & TableName and placed the pkCol on the fkCol, so we could do interrogate c.ParentColumn.TableName. I see ParentTable is now on the Column class so that wouldn't be needed. I think the FK is more complex now in that it handles multi-column FKs, so not sure where to go.

sjh37 commented 2 years ago

I tried but couldn't get it to work out of the box, so I am modifying the generator to allow you to do this. I'll make sure to tag the changeset with this case number so you can see the code change I have made.

sjh37 commented 2 years ago

Here is the changeset: https://github.com/sjh37/EntityFramework-Reverse-POCO-Code-First-Generator/commit/c10aad9b7cf47af151792a637b8de66eeab23e50

Add this to your .tt file:

Settings.AddEnum = delegate (Table table)
    {
        if (table.HasPrimaryKey && table.PrimaryKeys.Count() == 1 && table.Columns.Any(x => x.PropertyType == "string"))
        {
            // Example IF to only choose tables with a certain naming conventions for enums
            if (table.NameHumanCase.StartsWith("REF_", StringComparison.InvariantCultureIgnoreCase) ||
                table.NameHumanCase.EndsWith("_LUT", StringComparison.InvariantCultureIgnoreCase))
            {
                try
                {
                    Settings.Enumerations.Add(new EnumerationSettings
                    {
                        Name       = table.NameHumanCase + "Enum",
                        Table      = table.Schema.DbName + "." + table.DbName,
                        NameField  = table.Columns.First(x => x.PropertyType == "string").DbName, // Or specify your own
                        ValueField = table.PrimaryKeys.Single().DbName // Or specify your own
                    });
                }
                catch
                {
                    // Swallow exception
                }
            }
        }
    };

change NameField = "Name",

You can update your own .ttinclude file, or wait for the next release. Any problems add a commen.

sjh37 commented 2 years ago
public static Action<Table> AddEnum = delegate (Table table)
{
    if (table.HasPrimaryKey && table.PrimaryKeys.Count() == 1 && table.Columns.Any(x => x.PropertyType == "string"))
    {
        if (table.NameHumanCase.StartsWith("REF_", StringComparison.InvariantCultureIgnoreCase) ||
            table.NameHumanCase.EndsWith  ("_LUT", StringComparison.InvariantCultureIgnoreCase))
        {
            try
            {
                Enumerations.Add(new EnumerationSettings
                {
                    Name       = table.NameHumanCase.Replace("REF_","").Replace("_LUT","") + "Enum",
                    Table      = table.Schema.DbName + "." + table.DbName,
                    NameField  = table.Columns.First(x => x.PropertyType == "string").DbName,
                    ValueField = "Name"
                });

                // This will cause this table to not be reverse engineered.
                // This means it was only required to generate an enum and can now be removed.
                table.RemoveTable = true; // Remove this line if you want to keep it in your dbContext.
            }
            catch
            {
                // Swallow exception
            }
        }
    }
};
sjh37 commented 2 years ago

Now released in v3.6.0