The type must be a Reference type in order to use it as Parameter 'Tentity' in the Generic type or method 'Dbset<Tentity>'

Asked

Viewed 428 times

0

I am trying to set up an Enum in ENTITY FRAMEWORK. But I am not succeeding.

My Context is like this:

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

The Enum is 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 how I will register it in the Bank)

But this error is returning:

The type must be a Reference type in order to use it as Parameter 'Tentity' in the Generic type or method 'Dbset'

I used as a reference this link: https://msdn.microsoft.com/en-us/library/hh859576(v=vs.113). aspx

  • I believe that you can not make a Dbset of the type of an Enum ...

2 answers

4


Is not possible.

You need to pass a class to DbSet.

An Enum may be a property of a model, but never a model itself. That is, it is acceptable

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

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

0

You can make one class, that gets the Enum and that class is related to another that you need.

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

I use the following code:

  1. 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;
    }
    
  2. Two extension methods, to take the description and do 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));
      }
    
  3. Your enum:

    public enum MeuEnum
    {
       [Description("Em Aberto")]
        Aberta = 1,
    
       [Description("Fechado")]
        Fechada = 4,
    
       [Description("Aguardando alguma coisa")]
        Aguardando = 5
    }
    
  4. 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
    }
    
  5. Your Dbset:

    public DbSet<MeuEnumClass> Status { get; set; }
    
  6. Overwrite the Seed method of the EF configuration class:

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

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

  • Id: It is the PK and also the enum proper. (A whole shall be informed in the bank)

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

  • Description Is the value of the attribute Description informed on enum, for example "Open" in current code.

Code taken from: https://stackoverflow.com/a/44166999/4713574

I’m putting it to you as an answer in case someone might need something like this.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.