The type must be a reference type in order to use it as parameter 'TEntity' in the generic type or method 'DbSetTEntity'

0

I'm trying to set up an enum in ENTITY FRAMEWORK. But I'm not having success.

My Context looks like this:

public class MoradaWebContext : DbContext
{
 public DbSet<MeuEnum> Status { get; set; }
}

The Enum looks like this:

public enum MeuEnum
{
        Aberta = 1,
        Fechada = 4,
        Aguardando = 5,
}

And I wanted to leave it configured in the mapping correctly. Even in the bank. (I have to see even how I will register it in the Bank)

But you are returning this error:

  

The type must be a reference type in order to use it as parameter   'TEntity' in the generic type or method 'DbSet'

I used this link as a reference: link

    
asked by anonymous 16.03.2017 / 20:20

2 answers

4

Not possible.

You need to pass a class to DbSet .

An enum can be a property of a model, but never a model itself. That is, this is acceptable

public MeuModel 
{
    public MeuEnum Status { get; set; }
}

But what you're trying to do is not valid.

    
16.03.2017 / 20:24
0

You can make one class, which receives the enum and this class is related to the other one you need.

In other words, it will be a class where your primary key will be the enum.

I use the following code:

  • A Generic class, which receives the type of enum :

    public class EnumTable<TEnum>
        where TEnum : struct
    {
        public TEnum Id { get; set; }
        public string Nome { get; set; }
        public string Descricao { get; set; }
    
        protected EnumTable() { }
    
        public EnumTable(TEnum enumType)
        {
            if (!typeof(TEnum).IsEnum)
            {
                throw new Exception($"Argumento inválido do tipo {typeof(TEnum)}");
            }
    
            Id = enumType;
            Nome = enumType.ToString();
            Descricao = enumType.GetEnumDescription<TEnum>();
        }
    
        public static implicit operator EnumTable<TEnum>(TEnum enumType) => new EnumTable<TEnum>(enumType);
        public static implicit operator TEnum(EnumTable<TEnum> status) => status.Id;
    }
    
  • Two extension methods, to get the description and make the seed:

          public static string GetEnumDescription<TEnum>(this TEnum item)
    => item.GetType()
           .GetField(item.ToString())
           .GetCustomAttributes(typeof(DescriptionAttribute), false)
           .Cast<DescriptionAttribute>()
           .FirstOrDefault()?.Description ?? string.Empty;
    
    
    
      public static void SeedEnumValues<T, TEnum>(this IDbSet<T> dbSet, Func<TEnum, T> converter)
    where T : class
      {
              Enum.GetValues(typeof(TEnum))
                .Cast<object>()
                .Select(value => converter((TEnum)value))
                .ToList()
                .ForEach(instance => dbSet.AddOrUpdate(instance));
      }
    
  • Your enum :

    public enum MeuEnum
    {
       [Description("Em Aberto")]
        Aberta = 1,
    
       [Description("Fechado")]
        Fechada = 4,
    
       [Description("Aguardando alguma coisa")]
        Aguardando = 5
    }
    
  • Your class, inheriting the generic class, informing your enum:

    public class MeuEnumClass: EnumTable<MeuEnum>
    {
        public MeuEnumClass(MeuEnum enumType) : base(enumType)
        {
    
        }
    
        public MeuEnumClass() : base() { } //deve ser definido o construtor padrão para o EF
    }
    
  • Your DbSet:

    public DbSet<MeuEnumClass> Status { get; set; }
    
  • Override the EF configuration class Seed method:

    protected override void Seed(SeuDbContext context)
    {
        context.Status.SeedEnumValues<MeuEnumClass, MeuEnum>(@enum => new MeuEnumClass(@enum));
    }
    
  • Ready. Create migration and update the database.

  • The table with the Id, Name and Description fields will be created where:

    • Id: It is the PK and also the enum itself. (An integer is entered in the bank)

    • Name: Is the value of enum , for example "Open" in the current code

    • Description This is the value of the Description attribute entered in enum , for example "Opened" in the current code.

      

    Code removed from: link

    It answered perfectly, I am putting in answer if somebody needs something like this.

        
    21.02.2018 / 23:32