web-dev-qa-db-fra.com

Comment puis-je utiliser pour la première fois la base de données EF Core avec Enums?

J'utilise EF Core avec une approche de base de données en utilisant la commande "Scaffold-DbContext" pour générer mon DbContext/Entities.

Comment puis-je indiquer à Scaffold-DbContext qu'un certain field dans un certain table doit générer du code pour utiliser un Enum au lieu d'un simple int?

C’est comme cela que vous faisiez auparavant dans EF: https://www.devu.com/cs-asp/lesson-69-mapping-enum-types-entity-properties-framework-designer/

Exemple

Cette énumération est déjà définie dans le code:

public enum StateEnum {
  Ok = 1,
  Fail = 2
}

C’est ce que me donne Scaffold-DbContext

public partial class Foo
{
    public int Id { get; set; }
    public int State { get; set; }
}

C'est ce que je veux qu'il crée:

public partial class Foo
{
    public int Id { get; set; }
    public StateEnum State { get; set; }
}
10
Bassebus

À partir de Entity Framework Core 2.1, EF prend en charge Conversion de valeur pour traiter spécifiquement les scénarios dans lesquels une propriété doit être mappée vers un type différent pour le stockage.

Spécifiquement pour Enums, vous pouvez utiliser les EnumToStringConverter ou EnumToNumberConverter fournis.

6
Dejan

La conversion de valeur dans EF Core 2.1 ne répond-elle pas à vos besoins actuels?

https://docs.Microsoft.com/en-us/ef/core/modeling/value-conversions

Exemple rapide:

  entity.Property(e => e.MyEnumField)
            .HasMaxLength(50)
            .HasConversion(
                v => v.ToString(),
                v => (MyEnum)Enum.Parse(typeof(MyEnum),v))
                .IsUnicode(false);
11
MrKobayashi

Je suis arrivé à cause du titre de la question. Vous ne savez pas si cela fonctionne dans "Scaffold-DbContext", mais dans DbContext (Microsoft.EntityFrameworkCore 2.0.1.0) en définissant explicitement le type de base de l'énum, ​​même si le type sous-jacent par défaut d'éléments d'énumération est int. Vous pouvez également utiliser l'API Fluent pour définir les valeurs par défaut avec cette dernière (en particulier dans le cas où l'énumération commence par 1).

public enum StateEnum : int
{
    Ok = 1,
    Fail = 2
}

Les types approuvés pour une énumération sont byte, sbyte, short, ushort, int, uint, long ou ulong. 

Donc, je pense que cela fonctionnerait pour aucun de ceux-ci. enum (Référence C #)

public class MyDbContext : DbContext
{      
    protected override void OnModelCreating(ModelBuilder builder) 
    {
        builder.Entity<Foo>().Property(x => x.State).HasDefaultValue(StateEnum.Ok);
    }
}
11
A.J.Bauer

Actuellement, EF core ne prend pas en charge les énumérations . Code comme ceci:

public class MyDbContext : DbContext
{      
    protected override void OnModelCreating(ModelBuilder builder) 
    {
        builder.Entity<StateEnum>(e => {...});
    }
}

ne compile pas avec le message:

CS0452 C # Le type doit être un type de référence pour pouvoir être utilisé comme paramètre "TEntity" dans le type ou la méthode générique.

Solution: vous pouvez utiliser les classes d'énumération à la place

3
Rusich

Essayez cette solution: 

public enum StateEnum {
      Ok = 1,
      Fail = 2
}

public partial class Foo
{
    public int Id { get; set; }
    public int StateId { get; set; }
    public StateEnum State
    {
        get => (StateEnum)StateId;
        set => StateId = (int)value;
    }
}
2
Aliaksei Zhukau

C’est la même question dont la réponse est donnée à: EF7 prend-il en charge les enums?

2
schnitty

Vous pouvez avoir votre enum (U) et une entité (T) représentant des valeurs enum dans la base de données

public static T[] BuildEntityObjectsFromEnum<T, U>() where U: Enum where T : new()
    {
        var listObjectsToReturn = new List<T>();
        Dictionary<string, int> dictionary = Enum.GetValues(typeof(U)).Cast<U>().ToDictionary(t => t.ToString(), t =>  Convert.ToInt32(t));

        foreach (var item in dictionary)
        {
            var newObject = new T();
            Type classType = typeof(T);
            classType.GetProperties()[0].SetValue(newObject, item.Value); // Enum int id
            classType.GetProperties()[1].SetValue(newObject, item.Key); // Enum string value
            listObjectsToReturn.Add(newObject);
        }
        return listObjectsToReturn.ToArray();
    }

Ensuite, vous pouvez semer la table de l'énum

modelBuilder.Entity<T>().HasData(BuildEntityObjectsFromEnum<T,U>());
0
sofsntp