Nous avons besoin d’une expression de construction pour EF de manière dynamic. Par exemple, créez des modèles de test:
public class TestBase { public int Id { get; set; } } public class TestCard : TestBase { public Guid Guid { get; set; } }
Créez une requête linq:
var q = from card in Context.hlt_disp_Card select new TestCard { Id = card.disp_CardID, Guid = card.Guid };
Normal en utilisant des expressions:
Expression<Func> ex1 = card => card.Id == 1030; q.Where(ex1).ToList();
Nous avons besoin de créer une expression de n’importe quel type et nous avons toujours un nom de chaîne de propriété, nous avons donc essayé de le construire de cette manière:
var e = Expression.Parameter(typeof(TestCard), "card"); Expression bin = Expression.Property(e, "Id"); bin = Expression.Equal(bin, Expression.Constant(1030)); var ex2 = Expression.Lambda<Func>(bin, e); q.Where(ex2).ToList();
Mais nous avons eu un avertissement:
Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory [8] L’expression LINQ ‘(new TestCard () {Id = [carte] .disp_CardID, Guid = [carte] .Guid} .Id == 1030) n’a pas pu être traduite. sera évalué localement. Pour configurer cet avertissement, utilisez l’API DbContextOptionsBuilder.ConfigureWarnings (ID d’événement ‘RelationalEventId.QueryClientEvaluationWarning’). ConfigureWarnings peut être utilisé lors de la substitution de la méthode DbContext.OnConfiguring ou de l’utilisation de AddDbContext sur le fournisseur de service d’application.
Nous avons vérifié le résultat SQL dans le profileur et obtenu les résultats suivants: q.Where (ex1) .ToList (); construit pour
SELECT [card].[disp_CardID], [card].[Guid] FROM [hlt_disp_Card] AS [card] WHERE [card].[disp_CardID] = 1030
et q.Where (ex2) .ToList (); construit pour
SELECT [card].[disp_CardID], [card].[Guid] FROM [hlt_disp_Card] AS [card]
Et si j’essaie de construire un filtre pour les propriétés non héritées (par exemple Guid), mon chemin fonctionne bien!
Version EF Core: 1.0.1
Comment résoudre ce problème?
Wow, cela ressemble à un autre bogue EF Core (cela se produit également dans la v.1.1.0 (version)).
La seule différence entre les deux expressions est le ReflectedType
de l’expression d’ ReflectedType
de la propriété Member
.
Vous pouvez le réparer de cette façon:
// ... var p = e.Type.GetProperty("Id"); if (p.ReflectedType != p.DeclaringType) p = p.DeclaringType.GetProperty(p.Name); Expression bin = Expression.MakeMemberAccess(e, p); // ...
mais c’est bizarre d’avoir une telle exigence, je suggérerais de signaler le problème à EF Core GitHub .