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
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
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:
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é :
delegate bool MyDelegate<T>(T o) where T : UneInterface;
Et
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 :
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 :
- Mon expression accepte bien un seul paramètre de type 'MonNamespace.UneEntitéQuiImplementeUneInterface'
- Mon expression retourne bien un booléen
- 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...
Partager