Home > OS >  To seed type tables in Entity Framework I want a generic method that takes an enum and creates a lis
To seed type tables in Entity Framework I want a generic method that takes an enum and creates a lis

Time:01-10

To seed type tables in Entity Framework Core, I am rewriting this same code in the function 'StopLightColorTypeList' for every database type table that I need seed. I'm looking to create a generic method.

    modelBuilder.Entity<StopLightColorType> 
       ().HasData(WLProgramSeed.StopLightColorTypeList());

The StopLightColorTypeList takes each enumeration member creates a new StopLightColorType object and adds it to the list before:

Setting the object ID property to the int value of the Enum Setting the Name property to the string value of the Enum

I am looking to use generics in such a way where I can

  • Specify the enumeration type (in this case it's StopLightColorsEnum)
  • Specify the return type object (in this case it's StopLightColorType)
  • Specify what property to set for the ID (must be integer) (in this case it's StopLightColorID)
  • Specify what property to set for the name (must be a string) (in this case it's StopLightColorName)
  • Optionally specify a function to parse the enumeration name
using System;
using System.Collections.Generic;
using System.Linq;

namespace GenericEnumToTypeList
{
    class Program
    {
        static void Main(string[] args)
        {
            List<StopLightColorType> stopLightColorTypes = EFTools.StopLightColorTypes();

            foreach(var stopLightColorType in stopLightColorTypes)
            {
                Console.WriteLine("ID: {0} Name: {1}", stopLightColorType.StopLightColorID, stopLightColorType.StopLightColorName);
            }

            Console.ReadLine();
        }
    }

    public enum StopLightColorsEnum
    {
        Red = 1,
        Yellow = 2,
        Green = 3
    }

    public class StopLightColorType
    {
        public StopLightColorsEnum StopLightColorID { get; set; }
        public string StopLightColorName { get; set; }
    }

    public class EFTools
    {

        public static List<StopLightColorType> StopLightColorTypes()
        {
            List<StopLightColorType> stopLightColorTypes = new List<StopLightColorType>();

            foreach(StopLightColorsEnum stopLightColor in System.Enum.GetValues(typeof(StopLightColorsEnum))
            {
                StopLightColorType stopLightColorType  = new StopLightColorType
                {
                    StopLightColorID = stopLightColor,
                    StopLightColorName = ParseCapitalizedEnumName(stopLightColor.ToString())
                };

                stopLightColorTypes.Add(stopLightColorType);
            }

            return stopLightColorTypes;
        }

        public static string ParseUnderScoreName(string stringName)
        {            
            return stringName.Replace("_", " "); ;
        }

        public static string ParseCapitalizedEnumName(string enumName)
        {

            string typeName = enumName[0].ToString();

            for(int i = 1; i <= enumName.Length; i  )
            {
                if(Char.ToUpper(enumName[i]) == enumName[i])
                {
                    typeName = typeName   " "   enumName[i].ToString(); 
                }
            }

            return typeName;
        }

    }

}

I re-write this code for each database type, I'm looking for a generic to take care of this operation.

CodePudding user response:

The core function you need is this:

IEnumerable<TResult> ListEnumMembers<TEnum, TResult>(string valueName, string nameName)
    where TEnum : System.Enum
{
    var enumInfos = Enum.GetValues(typeof(TEnum)).Cast<int>()
        .Zip(Enum.GetNames(typeof(TEnum)), (i, s) => (Value: i, Name: s));
    
    var typ = typeof(TResult);
    var piValue = typ.GetProperty(valueName);
    var piName = typ.GetProperty(nameName);
    return enumInfos.Select(i =>
    {
        var instance = (TResult)Activator.CreateInstance(typ);
        piValue.SetValue(instance, i.Value);
        piName.SetValue(instance, i.Name);
        return instance;
    });
}

With this generic result type...

class EnumInfo
{
    public int Value { get; set; }
    public string Name { get; set; }
}

...and this code:

var enumInfos = ListEnumMembers<DayOfWeek, EnumInfo>("Value", "Name").ToList();

You get this result:

Value Name
0 Sunday
1 Monday
2 Tuesday
3 Wednesday
4 Thursday
5 Friday
6 Saturday

I guess this will put you on the right track. Of course the code needs a couple of checks for the property names and types.

  •  Tags:  
  • Related