IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

EF Core : Conversion d'un enum à 3 état en bool?


Sujet :

C#

  1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2010
    Messages : 185
    Points : 167
    Points
    167
    Par défaut EF Core : Conversion d'un enum à 3 état en bool?
    Bonjour,
    Je suis à la recherche d'un convertisseur générique d'un enum à 3 entrées en bool? (et pourquoi pas 2 en bool).

    Dans un premier temps, j'ai trouvé une façon assez simple de le faire avec HasConvertion<MonEnum> :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
    
                var values = Enum.GetValues(typeof(MonEnum))
                                 .Cast<MonEnum>()
                                 .ToList();
    
                modelBuilder.Entity<MonObjet>()
                            .Property(o => o.MaPropriete)
                            .HasColumnType(typeof(bool?).Name)
                            .HasConversion<MonEnum>(o => o == values.Min() ? null : o == values.Max(),
                                           o => o == MonEnum.Value1 ? values.Min() : o == MonEnum.Value3 ? values.Max() : values[1]);
            }

    Le <MonEnum> souligné n'est pas obligatoire, C# reconnaissant le type.

    Le problème de cette méthode est que je dois faire cela pour chaque propriété de chaque champ ayant un enum à 3 entrées et j'aimerais que ce soit automatique et générique sans avoir <MonEnum> alors j'ai préparé ce code pour tenter d'y répondre :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
              modelBuilder.Model
                          .GetEntityTypes()
                          .ForEach(o => o.GetProperties()?
                                         .Where(p => o.ClrType.GetProperty(p.Name)?.PropertyType.IsEnum == true)
                                         .ForEach(
                                                p =>
                                                {
                                                    var propertyType = o.ClrType.GetProperty(p.Name)?.PropertyType;
     
                                                    if (!propertyType.IsEnum)
                                                        propertyType = propertyType?.GenericTypeArguments[0];
     
                                                    var dico = new SortedDictionary<int, string>();
     
                                                    foreach (int item in propertyType.GetEnumValues())
                                                        dico[item] = propertyType.GetEnumName(item);
     
                                                    var property = builder.Entity(o.Name)
                                                                          .Property(p.Name);
     
                                                    if (dico.Count == 3)
                                                    {
                                                        property.HasColumnType(typeof(bool?).Name);
     
                                                        var converter = new BoolNullableConverter(propertyType, dico);
     
                                                        property.HasConversion(converter);
                                                    }
                                                }));
    Avec le convertisseur suivant :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
        public class BoolNullableConverter : ValueConverter<Enum, bool?>
        {
            public BoolNullableConverter(
                Type propertyType,
                SortedDictionary<int, string> keyValuePairs,
                ConverterMappingHints? mappingHints = null)
                : base(o => o == (Enum)Enum.ToObject(propertyType, keyValuePairs.First().Key) ?
                            null :
                            o == (Enum)Enum.ToObject(propertyType, keyValuePairs.Last().Key),
                       o => o == null ?
                            (Enum)Enum.ToObject(propertyType, keyValuePairs.First().Key) :
                            o == true ?
                            (Enum)Enum.ToObject(propertyType, keyValuePairs.Last().Key) :
                            (Enum)Enum.ToObject(propertyType, keyValuePairs.Take(2).Last()),
                       mappingHints)
            {
            }
        }

    Heureux que visual studio ne râle pas sur mon code, je lance le truc, et là
    "Converter for model type 'Enum' cannot be used for 'MonObjet.MaPropriete' because its type is 'MonEnum'."

    Quelle est mon erreur ? Auriez-vous le petit bout de code me permettant de faire ce que je cherche à faire ?
    Et si vous voyez quelques maladresse ou améliorations dans mon code, je prends

    Merci d'avance et bonne Ascension...

    Infos techniques : Framework 4.8 + EF Core 3.14

  2. #2
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2010
    Messages
    185
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2010
    Messages : 185
    Points : 167
    Points
    167
    Par défaut Pour ceux que cela peut intéresser
    Bonsoir,
    Voilà, j'ai trouvé ma réponse, je ne sais plus où, si utilisation d'un convertisseur alors le champ n'accepte pas de valeur null.
    Du coup, je ne peux pas faire ça directement mais j'ai une autre solution :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public enum MyEnum { V1, V2, V3 }
        public class MyClass
        {
            [NotMapped]
            public MyEnum MaPropriete{ get; set; }
     
            public bool? MaProprieteTripleState { get => MaPropriete.TriState(); set => MaPropriete= value.TriState<MonEnum>(); }
     
        }

    Et dans une class static, pour une extension :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            public static bool? TriState<T>(this T This) where T : Enum
            {
                var values = Enum.GetValues(typeof(T))
                       .Cast<T>()
                       .ToList();
     
                return This.Equals(values.Min()) ? null : This.Equals(values.Max());
            }
     
            public static T TriState<T>(this bool? This) where T : Enum
                => ((bool?)This).TriState<T, bool?>(true, false, true);
    Qu'en pensez-vous ?

    De plus, j'ai appris la raison pour laquelle on utilise un virtual pour les collections, d'après ce lien, https://stackoverflow.com/questions/...active#tab-top :
    Chaque ICollection est chargée sans mettre de Include...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. conversion directe int -> enum
    Par Ghurdyl dans le forum Débuter
    Réponses: 3
    Dernier message: 11/08/2009, 08h55
  2. Conversion entre un "enum" et l'index (int) d'une table
    Par Chavadam dans le forum Langage
    Réponses: 4
    Dernier message: 27/07/2009, 18h20
  3. [Framework] [Spring Core] conversion de valeur pour un constructeur
    Par robert_trudel dans le forum Spring
    Réponses: 1
    Dernier message: 01/09/2008, 09h16
  4. Réponses: 5
    Dernier message: 14/02/2007, 16h43
  5. Conversion Enum <-> byte
    Par Don ViP dans le forum Langage
    Réponses: 5
    Dernier message: 03/05/2006, 14h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo