Bonsoir à tous et meilleurs voeux pour 2022,
Je sollicite votre aide (encore une fois) pour une situation que je n'arrive pas à résoudre.
Je cherche à faire un filtre avec EFCore 3 et voici la premier test
Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<UneEntitéQuiImplementeUneInterface>().HasQueryFilter(o => o.MaPropriete == null);
        }

Ce code fonctionne (ouf).

J'ai aussi essayé comme ça
Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<UneEntitéQuiImplementeUneInterface>().HasQueryFilter(o => EF.Property<DateTime?>(o, nameof(UneInterface.MaPropriete)) == null);
        }

Et ça fonctionne aussi...

Super mais j'aimerais bien scanner l'ensemble de mes entités pour appliquer le même filtre et j'ai naturellement écrit ceci:
Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Model
                      .GetEntityTypes()
                      .Where(o => o.ClrType.GetInterface(typeof(UneInterface).Name) != null)
                      .ToList()
                      .ForEach(o => modelBuilder.Entity(o.ClrType).HasQueryFilter(o => o.MaPropriete== null));
        }

Et là les ennuies commence, Visual Studio me dit "Impossible de convertir expression lambda en type 'LambdaExpression', car il ne s’agit pas d’un type délégué"
Vous me direz, normal, VS ne sait pas sur quel objet il travaille donc il ne comprend pas l'expression lambda.
Mais même avec l'autre forme qui ne dépend plus vraiment de mon objet, ben ça me met le même message d'erreur.

OK, il veut un délégué, alors je code un délégué :
Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
delegate bool MyDelegate<T>(T o) where T : UneInterface;
Et
Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            MyDelegate<UneInterface> myDelegate = o => o.MaPropriete== null;
            modelBuilder.Model
                      .GetEntityTypes()
                      .Where(o => o.ClrType.GetInterface(typeof(UneInterface).Name) != null)
                      .ToList()
                      .ForEach(o =>modelBuilder.Entity(to.ClrType).HasQueryFilter(o => myDelegate(o)));
        }

Toujours la même erreur

Pourquoi n'arrive-je pas à le faire car là c'est un délégué non de non...

Puis la malice me prend :
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
            modelBuilder.Model
                      .GetEntityTypes()
                      .Where(o => o.ClrType.GetInterface(typeof(UneInterface).Name) != null)
                      .ToList()
                      .ForEach(
                            o =>
                            {
                                ParameterExpression paramExp= Expression.Parameter(typeof(UneInterface));
                                ConstantExpression constExp = Expression.Constant(null, typeof(DateTime?));
                                MemberExpression memberExp = Expression.Property(numParam, nameof(UneInterface.MaPropriete));
                                BinaryExpression binExp = Expression.Equal(memberExpression, constExp );
 
                                var filter = Expression.Lambda<Func<UneInterface, bool>>(binExp, new[] { paramExp});
 
                                modelBuilder.Entity(o.Name).HasQueryFilter(filter);
                            });

Et là, nickel, plus d'erreur à la compilation.

J'exécute et tout se passe bien exceptée la dernière ligne => The filter expression 'Param_0 => (Param_0.DissociationDate == null)' specified for entity type 'UneEntitéQuiImplementeUneInterface' is invalid. The expression must accept a single parameter of type 'MonNamespace.UneEntitéQuiImplementeUneInterface', return bool, and may not contain references to navigation properties.

Bon alors vérifions ça :
  1. Mon expression accepte bien un seul paramètre de type 'MonNamespace.UneEntitéQuiImplementeUneInterface'
  2. Mon expression retourne bien un booléen
  3. Mon expression n'a pas de référence de navigation


Alors où est le problème ?

Si quelqu'un a une idée car là je suis tout sec, j'ai abattu toutes mes cartes pour le coup là... Enfin non, il me reste developpez.net

Merci d'avance

P.S. : J'ai aussi tenter de mettre Expression.Parameter(o.ClrType) mais là c'est à la construction du filtre que cela ne se passe pas bien => Impossible d'utiliser le ParameterExpression de type 'MonNamespace.UneEntitéQuiImplementeUneInterface' pour le paramètre de délégué de type 'MonNamespace.UneInterface'
Et bien sûr, je ne peux pas le mettre dans mon expression lambda...