We need construct expression for EF in dynamic way. For example create test models:
public class TestBase
{
public int Id { get; set; }
}
public class TestCard : TestBase
{
public Guid Guid { get; set; }
}
Create a linq query:
var q = from card in Context.hlt_disp_Card
select new TestCard
{
Id = card.disp_CardID,
Guid = card.Guid
};
Normal using expressions:
Expression<Func<TestCard, bool>> ex1 = card => card.Id == 1030;
q.Where(ex1).ToList();
We require create expression from any type and always we have a string name of property, thus we tried construct it in this way:
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<TestCard, bool>>(bin, e);
q.Where(ex2).ToList();
But we got a warning:
Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory[8]
The LINQ expression '(new TestCard() {Id = [card].disp_CardID, Guid =
[card].Guid}.Id == 1030)' could not be translated and will be
evaluated locally. To configure this warning use the
DbContextOptionsBuilder.ConfigureWarnings API (event id
'RelationalEventId.QueryClientEvaluationWarning'). ConfigureWarnings
can be used when overriding the DbContext.OnConfiguring method or
using AddDbContext on the application service provider.
We checked resulting SQL in profiler and got this results:
q.Where(ex1).ToList(); built to
SELECT [card].[disp_CardID], [card].[Guid]
FROM [hlt_disp_Card] AS [card]
WHERE [card].[disp_CardID] = 1030
and q.Where(ex2).ToList(); built to
SELECT [card].[disp_CardID], [card].[Guid]
FROM [hlt_disp_Card] AS [card]
And if I try construct filter for not-inherited property (eg Guid) my way works well!
EF Core version: 1.0.1
How to solve this problem?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…